字串是否若干字元組成的序列。 由於字串在程式設計時使用的頻率非常高,為了優化,很多語言都對字串做了特殊的規定.
c/c++中每個字串都以字元'\0'
作為結尾,這樣我們就能很方便地找到字串最後尾部.
但由於這個特點, 每個字串中都有乙個額外的字元開銷,稍不留神就會造成字串的越界.
char str[10];
strcpy(str, "0123456789");
我們先宣告乙個長度為10的字元陣列,然後把字串"0123456789"複製到陣列中. "0123456789"看起來只有10個字元, 但實際上它的末尾還有乙個』\0』字元,因此它的實際長度為11位元組.
要正確的複製該字串,至少需要乙個長度為11位元組的陣列.
為了節省記憶體, c/c++把常量字串放到單獨的乙個記憶體區域.當幾個指標賦值給相同的常量字串時,他們實際上會指向相同的記憶體位址. 但用常量記憶體初始化陣列,情況卻有所不同,下面通過乙個面試題來學習這一知識點. 執行下面的**, 得到的結果是什麼?
#include using namespace std;
int main(int ar**, const char* argc)
str1 和 str2 是兩個字串陣列,我們會為他們分配兩個長度為12位元組的空間, 並把"hello world"的內容分別賦值到陣列中去. 這是兩個初始位址不同的陣列, 因此str1 和 str2的值也不相同.
str3 和 str4 是兩個指標,我們無須為他們分配記憶體以儲存字串的內容,而只需要把他們指向"hello world"在記憶體中的位址就可以了,由於"hello world"是常量字串,他在記憶體中只有乙個拷貝,因此str3 和 str4 指向同乙個位址.
tip在網路程式設計中,如果url引數含有特殊字元,如空格,"#"等, 則可能導致伺服器端無法獲取正確的引數,我們需要將這些特殊字元轉換成伺服器可以識別的字元.轉換的規則是在』%『的後面跟上ascii碼的兩位十六進製制表示. 比如空格的ascii碼是32, 即十六進製制的0x20, 因此空格被替換成%20, 再比如』#'的ascii碼為35,即表示為0x23, 他在url中被替換為%23.
看到這個題目, 我們首先應該想到的是原來乙個空格字元, 替換之後變成'%', '2'和'0' 這3個字元,因此字串會變長, 如果是在原來的字串上進行替換, 就有可能覆蓋修改再該字串後面的記憶體.
如果是建立新的字串並在新的字串上進行替換,那麼我們可以自己分配足夠多的記憶體.
由於有兩種不同的解決方案,我們應該向面試官問清楚,讓他明確告訴我們他的需求,假設面試官讓我們在原來的字串長進行替換,並且保證輸入的字串後面有足夠多的空餘記憶體.
解法一: 時間複雜度為o(n^2), 不足以拿到offer
遍歷原字元陣列, 遇到空格, 在把空格所在位置後面的元素往後移兩個位置。 需要保證陣列足夠長。你會發現空格後面的字元可能存在被移動多次的可能。 解法二對這個問題就行了優化。
解法二: 時間複雜度為o(n),搞定offer就靠他了
先遍歷一次字串,統計空格的個數,並可以由此計算出替換之後字串的總長度,我們從字串的後面開始複製和替換,這樣就避免了後面的字元可能移動多次的情況。
answer
解法一: string_blank_replace1.cpp
解法二: string_blank_replace2.cpp
本題考點:
舉一反三:
在合併兩個陣列(包括字串)時,如果從前往後複製每個數字(或字元)則需要移動數字(或字元多次),那麼我們可以考慮從後往前複製,這樣就能減少移動的次數,從而提高效率。
劍指offer筆記
對於這道題來說,書上的和leetcode上的是不一樣的。在leetcode上,是一位陣列中判斷是否有重複數字,有的話任意返回乙個就行。這個思路也有兩個 1.先用乙個排序如快排o nlogn 然後就判斷相鄰元素是否相等,若相等直接返回即可。2.用乙個集合set,遍歷陣列放進去,因為集合有唯一性,若哪個...
劍指Offer 0220 閱讀記錄
在這裡插入描述 1.談跳槽 現在的工作做了一段時間,已經沒有太多的激情了,因此希望尋找乙份更有挑戰的工作。然後具體論述為什麼有些厭倦現在的職位,以及面試的職位我為什麼會有興趣。2.技術面試 紮實的基礎知識 能寫高質量的 分析問題時思路清晰 能優化時間效率和空間效率,以及學習溝通等各方面的能力。3.應...
劍指offer筆記整理
本部落格借鑑了這篇部落格的版面設計,以及部分解題思路,主要用於個人劍指offer的刷題過程中的筆記整理。鍊錶部分 8道 劍指offer 三 從尾到頭列印鍊錶 劍指offer 十四 鍊錶中倒數第k個結點 劍指offer 十五 反轉鍊錶 劍指offer 十六 合併兩個排序的鍊錶 劍指offer 二十五 ...