字串中相同且長度最長的字串

2021-06-13 03:00:10 字數 1656 閱讀 5692

題目出自:《程式設計師面試寶典》(第三版) p226頁  面試例題2

輸入一行字串,找出其中出現的相同且長度最長的字串,輸出它及首字元的位置。例如「yyabcdabjcabceg」,輸出結果應該為abc和3。

這個題目存在乙個歧義,例如如果測試字串為aaaaaa,我一開始以為結果是長度為3的aaa,原來正確答案是長度為5的aaaaa。即2個等長的子串可以有部分字元重疊。因此,面試前最好問仔細點題目意圖,免得自己把自己給坑了。

首先,這題的2個for迴圈中的那個if語句明顯多於,這個if語句可以放到j的for迴圈中去,  即for(int j=0;j再者,書上給的程式有乙個小bug,例如輸入測試例子abba,沒有任何輸出結果,理論上應該輸出a:1或者b:2。當測試例子為abca,也沒有任何輸出結果,理論上應該輸出a:1。 這是因為尋找相同的子串時,程式忽略了長度為1的子串,當然這也可能是題目本意。如果不忽略長度為1的子串,直接修改i變數的下限,令for中的i>=1即可。

書中程式思想: 按照長度遞減去尋找相同的子串,只要找到第一對相同的子串,則立刻退出程式。因為是按照長度遞減的順序去尋找子串,所以必定能找到最長的相同子串。

以abcab為例子分析如下:

首先尋找長度為4的子串,只能是abca和bcab,再檢視這兩個子串是否有其他相同的子串。有的話直接輸出結果並退出程式。

然後尋找長度為3的子串,只能abc,bca,cab。這3個子串都沒有其他相同的子串。

最後尋找長度為2的子串,首先是ab,用find函式返回在abcab中正序查詢的位置0,用rfind函式返回在abcab中逆序查詢的位置3。這兩個位置不相等,說明在不同的位置存在相同的子串ab。直接輸出ab:1,然後退出程式。

法二:這道題目和前面的面試例題1非常相似,因此兩者的思想也相似,法二的**也是在面試例題1的方法二的**基礎上稍作修改。

相同子串的首字元必定相等,因此依次遍歷str的每個字元作為相等子串的首字元,然後在str中搜尋與首字元相等的字元,然後從這兩個相等的首字元開始,依次比較下乙個字元是否相等,相等的話字元長度就會增加,直到下乙個字元不等為止或者到了字串的末尾。然後把這長度最大的值存放在maxlen中,最後返回長度最大的子串和起始字元的下標。

程式源**如下,fun函式是書上的源**,封裝成函式形式,去掉if語句後j的範圍優化為j<=len-i,同時i的下限變成i>=1,其他不變。fun1是法二的版本。

#include#includeusing namespace std;

//書上的源**,封裝成函式形式,j的範圍優化了一下,同時i的下限變成i>=1,其他不變

pairfun(const string &str)

} }

return make_pair(count,substr);

}

pairfun1(const string& str)

k=j;

}//else

}//while

return make_pair(index,substr);

}

int main()

{

string str;

pairrs;

while(cin>>str)

{ rs=fun(str);

cout<1;--i){

for(j=0;j

字串中的最長重複字串

求乙個字串中的最長重複字串 基本思路是利用next陣列來實現 next陣列的定義 就是 字串中第j個字元 必有next j 1個重複 字串,事實上 kmp查詢 求模式串next陣列 就是指求出模式串j個 字元前 最大的重複子串 include include include include defi...

字串中出現相同並且長度最長的子串

題目描述 在字串中找到出現相同的並且長度是最長的子串,輸出該子串以及其首字元的位置。例如mainstr yyabcdabjcabceg 輸出為 abc 和3。分析 每次都找到最大長度的子串,然後正序和逆序查詢該子串出現的位置。如果兩者位置不相等,則說明兩子串是相同的並且長度最長的子串,滿足條件。否則...

統計字串相同且連續字元的數目

昨天同事給我看了一道面試題目,說的是給任意乙個字串,比如 aaaabbccazzggggg 然後寫乙個函式,最後將字串輸出為a4b2c2a1z2g5。起初自己想偏了,想用遞迴來做,想的相對比較複雜。遞迴應該是可以的,有時間再好好研究一下 後來重新整理一下思路,很快就寫出來了。php 如下 funct...