劍指offer 面試題4 替換空格

2021-07-31 02:59:14 字數 1639 閱讀 9008

題目由來:在網路程式設計中,如果url引數中含有特殊字元,如空格、「#」等,可能導致伺服器端無法獲得正常的引數值。我們需要將這些特殊符號轉換成伺服器可以識別的字元。轉換的規則是在%後面跟上ascii碼的兩位十六進製制的表示。比如空格的ascii碼是32,即十六進製制的0x20,因此空格被替代成「%20」。

思路分析:

將1個空格替換成3個字元,字串長度肯定會變長。那麼會產生兩種替換方法:

1、在原字串基礎上替換,這需要保證原字串可用長度能夠滿足替換後的需求。

2、自己重新分配足夠多的記憶體

我們假設這道題是在原字串基礎上替換,並且保證輸入的字串後面有足夠多的空閒記憶體。

最容易想到的想法是從前向後遍歷字串,遇到空格之後,將空格替換為%20,該空格之後的字元統一向後移2位。

假設字串的長度為n,對每個空格而言,需要移動後面o(n)個字元,因此對含有o(n)個空格字元的字串而言,總的時間效率是o(n^2)。

那麼我們能不能找到更優的解法呢?

可以考慮從後向前遍歷替換:

1、首先先遍歷一邊字串,統計出字串中空格的總數,以及該string原來的有效長度(包含末尾的\0)。每替換乙個空格,這樣我們可以求出替換後字串的總長度。

2、準備兩個指標p和q,p指向原始字串的末尾(\0),q指向替換後的字串的末尾。

3、從後向前遍歷原始字串,不是空格,直接將p賦值給q,是空格,則在q之前插入"%20"。

4、當p和q指向同一位置,表示所有的空格都已經替換完畢。

時間複雜度分析:所有的字元都只複製(移動)一次,因此該演算法的效率為o(n)。

**:

#include using namespace std;

void replaceblank(char string, int length)

int newlength = original + numofblank * 2;//將空格替換掉之後的長度

if(newlength > length)//判斷替換後陣列長度是否會超過陣列的容量

return;

int p = original;//指向string的'\0'

int q = newlength;

while(p >= 0 && q > p)

else

-- p; }}

int main()

測試用例:

1、輸入的字串中包含空格(空格位於字串的最前面,空格位於字串的最後面、空格位於字串的中間,字串中有連續多個空格)

2、輸入的字串中沒有空格

3、特殊輸入測試(字串是個null指標、字串是個空字串、字串中只有乙個空格字元、字串中只有連續多個空格)

本題考點:

1、考察字串程式設計能力。

2、考察分析時間效率的能力。我們要能清楚的分析前後兩種不同方法的時間效率各是多少。

3、考察對記憶體覆蓋是否有高度的警惕。在分析得知字串長度會變長之後,我們能夠意識到潛在的問題,並主動和面試官溝通以尋找問題的解決方案。

4、考察思維能力。從前到後的思路被否定之後,我們能否快速想到從後往前替換的方法。

舉一反三:

合併兩個陣列(包括字串)時,如果從前往後複製每個數字(或字元)需要重複移動次數較多,那麼我們可以考慮從前往後複製,這樣就能減少移動的次數,從而提高效率。

替換空格(劍指offer面試題4)

分析 從頭到尾掃瞄字串,遇到空格就替換,導致後面的字元都要向後移,意味著總時間複雜度為o n 2 更好的辦法,從字串後面遍歷替換。先遍歷所有的空格,每多乙個空格,字串長度加2個,也就是說最後替換後的字串長度為原長度 2 空格數,設定兩個指標,指向原始字串末尾和新字串末尾,依次向前遍歷,原始字串指標遇...

劍指offer 面試題4 替換空格

由於我在實現的時候使用的是c 的string,所以從後往前複製和從前往後複製,時間複雜度是一樣的。如果使用char 陣列實現,則從後往前複製更高效。重點是掌握這種反向思維。class solution 初始化新string string res s.size 2 countblank,a 必須將si...

劍指offer 面試題4 替換空格

class solution after length before length black length 2 最終字串的長度。原來有乙個空格,現在變成了三個字元 2 0 if after length length return int after index after length 定義兩個...