一道百度面試題

2021-06-23 09:50:42 字數 1633 閱讀 9900

下面這段**是把中英文混合字串(漢字用兩個位元組表示,特點是第乙個位元組的最高位為1)中的大寫字母轉化為小寫字母,請找出其中的bug,注意各種異常情況。

for (char *piterator = szword; *piterator != 0; piterator++) 

else if (*piterator >= 'a' && *piterator <= 'z')

}對於這個問題,我首先分析一下題目本身:

1.演算法的基本思路比較清晰:遍歷整個字串,找出其中的大寫的英文本元,然後把這些大寫的英文本元轉化成小寫字元。

2.當字串中某個位元組的最高位是1,則這個位元組和後面緊接著的乙個位元組組成了乙個漢字字元。

3.對於字串中佔兩個位元組的漢字字元,我們應該跳過這個漢字字元,繼續搜尋後面的字元。

有了這樣的乙個基本認識,我接著又考慮了一些細節的問題:

q1:對於這樣的字串,我們用什麼資料型別來儲存其中的每個位元組?

我們知道,ascii編碼的字元可以用signed char來儲存,因為ascii編碼的字元的取值範圍在[0,127],正好和signed char所能表示的正整數吻合。如果超出了這個範圍,signed char就會溢位。本題的字串中包含大於這個範圍的值(位元組的最高位是1),所以用signed char就不合適了,這時候就應該考慮unsigned char。

q2:對於這樣的字串,我們用什麼方式來表示字串的結束?

我們知道,對於用ascii編碼的字串,我們用'\0'字元來表示字串的結束。對於本題中的字串,該怎樣表示字串的結束?我也不能確定,暫時還用'\0'來表示吧。

q3:對於漢字字元,它佔兩個位元組,第乙個位元組的最高位是1,那第二個位元組有什麼特徵?

從題目中看不出來有什麼特徵。所体它可能是'\0',也可能是acsii編碼的字元,也可能是其他字元。

好了,有了以上理論上的分析,我在原來**的基礎上寫乙個修改的版本:

for (unsigned char *piterator = szword; *piterator != '\0'; piterator++)

else if ((*piterator & 0x80))else }}

**的分析:

1.我使用unsigned char來替換char。

2.對於漢字字元,我們只知道它的第乙個字元的特徵,我們卻不知道第二個字元的特徵,這樣就存在一些特殊的情況:

2.1 漢字的第二個字元是'\0'。我們有可能把這個字元看作是整個字串的結束字元,也就是字串的最後的乙個字元。這時候如果我們試圖跳過這個字元去獲取它後面的字元,就會發生字串的"越界"錯誤。為了避免這樣的錯誤,如果漢字的第二個字元是'\0',就不跳過這個字元。

2.2 漢字的第二個字元是英文的大寫字母。在原先的**中如果檢測到某個字元是漢字字元的第乙個字元,會將指標調整到這個漢字字元的第二個位元組,接著又判斷這個位元組是否是大寫字母,這時候就有可能將這個字元看作是大寫字母,這樣就發生了錯誤。為了避免這樣的錯誤,我將判斷是否是大小字母的**放到前面。

3.另外的乙個錯誤就是,由於"!="的優先順序大於"&"的優先順序,原先的**:

*piterator & 0x80 != 0

被編譯器解析成:

(*piterator) & (0x80 != 0)

這樣出來的結果就是錯誤的。為了避免這樣的錯誤,我刪除了"不等於0"的比較。

一道百度面試題

給出乙個整型陣列num,對其中的每個元素,輸出在它左側且比它小的最近元素,要求時間複雜度為o n 例如int num 2無左側最近元素 4左側最近的是2 1沒有 3左側最近的是1.分析 建立乙個棧,然後將陣列中的元素從右至左依次壓入棧中。對每個元素,入棧前先檢查棧頂元素是否比它大,若是的話,則該元素...

百度一道面試題

我這裡複製的是原話,當然順序是不一定的,很多拿到題目第一反應就是用map,當然可以解決,但是效率不高。還有人覺得應該用演算法 我是沒想到用啥演算法好.還有覺得應該先排序.還有覺得用位圖.bitmap 等等方法!我都覺得麻煩,思維方式就是,從節省時間考慮,從陣列來看,我們都得遍歷一次陣列裡面的元素,那...

憶一道百度面試題

題意 題目大概的意思是有乙個n x n的矩陣方格,在這個矩陣中有m個硬幣,每個硬幣的位置事先知道,且乙個格仔最多只能放乙個硬幣,現有乙個機械人從 0,0 的位置開始走,每次只能向下或者向右走一格,最終到達 n,n 設計程式計算機械人能拿到的最大的硬筆數。看到這個題目一看就是乙個動態規劃的問題。既然是...