面試演算法學習 2 字串包含

2021-07-25 20:47:39 字數 2592 閱讀 4708

給定兩個分別由字母組成的字串a和字串b,字串b的長度比字串a短。請問,如何最快地判斷字串b中所有字母是否都在字串a裡?

為了簡單起見,我們規定輸入的字串只包含大寫英文本母,請實現函式bool stringcontains(string &a, string &b)

比如,如果是下面兩個字串:

string 1:abcd

string 2:bad

答案是true,即string2裡的字母在string1裡也都有,或者說string2是string1的真子集。

如果是下面兩個字串:

string 1:abcd

string 2:bce

答案是false,因為字串string2裡的e字母不在字串string1裡。

同時,如果string1:abcd,string 2:aa,同樣返回true。

題目描述雖長,但題意很明了,就是給定一長一短的兩個字串a,b,假設a長b短,要求判斷b是否包含在字串a中。

初看似乎簡單,但實現起來並不輕鬆,且如果面試官步步緊逼,乙個乙個否決你能想到的方法,要你給出更好、最好的方案時,恐怕就要傷不少腦筋了。

判斷string2中的字元是否在string1中?最直觀也是最簡單的思路是,針對string2中每乙個字元,逐個與string1中每個字元比較,看它是否在string1中。

**可如下編寫:

bool

stringcontain

(string &a,string &b)

}return

true;

}

假設n是字串string1的長度,m是字串string2的長度,那麼此演算法,需要o(n*m)次操作。顯然,時間開銷太大,應該找到一種更好的辦法。

如果允許排序的話,我們可以考慮下排序。比如可先對這兩個字串的字母進行排序,然後再同時對兩個字串依次輪詢。兩個字串的排序需要(常規情況)o(m log m) + o(n log n)次操作,之後的線性掃瞄需要o(m+n)次操作。

//注意a b中可能包含重複字元,所以注意a下標不要輕易移動。這種方法改變了字串。如不想改變請自己複製

bool

stringcontain

(string &a,string &b)

if ((pa >= a.length()) || (a[pa] > b[pb]))

//a[pa] == b[pb]

++pb;

}return

true;

}

有沒有比快速排序更好的方法呢?

我們換一種角度思考本問題:

假設有乙個僅由字母組成字串,讓每個字母與乙個素數對應,從2開始,往後類推,a對應2,b對應3,c對應5,......。遍歷第乙個字串,把每個字母對應素數相乘。最終會得到乙個整數。

利用上面字母和素數的對應關係,對應第二個字串中的字母,然後輪詢,用每個字母對應的素數除前面得到的整數。如果結果有餘數,說明結果為false。如果整個過程中沒有餘數,則說明第二個字串是第乙個的子集了(判斷是不是真子集,可以比較兩個字串對應的素數乘積,若相等則不是真子集)。

思路總結如下:

按照從小到大的順序,用26個素數分別與字元'a'到'z'一一對應。

遍歷長字串,求得每個字元對應素數的乘積。

遍歷短字串,判斷乘積能否被短字串中的字元對應的素數整除。

輸出結果。

如前所述,演算法的時間複雜度為o(m+n)的最好的情況為o(n)(遍歷短的字串的第乙個數,與長字串素數的乘積相除,即出現餘數,便可退出程式,返回false),n為長字串的長度,空間複雜度為o(1)。

//此方法只有理論意義,因為整數乘積很大,有溢位風險

bool

stringcontain

(string &a,string &b)

; int f = 1;

for (int i = 0; i < a.length(); ++i)

}for (int i = 0; i < b.length(); ++i)

}return

true;

}

此種素數相乘的方法看似完美,但缺點是素數相乘的結果容易導致整數溢位。

如果面試官繼續追問,還有沒有更好的辦法呢?計數排序?除了計數排序呢?

事實上,可以先把長字串a中的所有字元都放入乙個hashtable裡,然後輪詢短字串b,看短字串b的每個字元是否都在hashtable裡,如果都存在,說明長字串a包含短字串b,否則,說明不包含。

再進一步,我們可以對字串a,用位運算(26bit整數表示)計算出乙個「簽名」,再用b中的字元到a裡面進行查詢。

// 「最好的方法」,時間複雜度o(n + m),空間複雜度o(1)

bool

stringcontain

(string &a,string &b)

for (int i = 0; i < b.length(); ++i)

}return

true;

}

這個方法的實質是用乙個整數代替了hashtable,空間複雜度為o(1),時間複雜度還是o(n + m)。2

1、變位詞1

面試演算法 字串(二)

kmp演算法可以用來解決字串匹配問題。現在有兩個字串,str1長度為n和str2長度為m且n m,判斷是否存在str1中包含str2 也就是判斷str2是否是str1的子串 如果存在,則返回true,如果不存在則返回false。我們一般的思路是,從str1的第乙個字元開始,擷取和str2相同長度的子...

002字串包含

2014.6.17 題目描述 給定兩個分別由字母組成的字串a和字串b,字串b的長度比字串a短。請問,如何最快地判斷字串b中所有字母是否都在字串a裡?為了簡單起見,我們規定輸入的字串只包含大寫英文本母,請實現函式bool stringcontains string a,string b 比如,如果是下...

面試筆記2(字串)

1.子串的定義時 串中任意個連續的字元組成的子串行,並規定空串是任意串的子串,任意串是其自身的子串。子串行則不要求字元連續,但順序與其在主串中相一致。2.字串末尾的 0意義同0,在c c 中0被轉化為bool型別的false,在條件語句中。3.printf語句在輸出字串時,將 0當做字串的結尾。4....