連續重複子字串查詢
阿新 • • 發佈:2019-02-01
本題來自2018深信服提前批筆試程式設計題部分。
題目描述:
一個重複子字串是由兩個相同的字串首尾拼接而成,例如abcabc便是長度為6的一個重複字串,而abcba則不存在重複字串。
給定任意字串,請幫小強找出其中的最長重複子串。
輸入描述:
輸入一個字串s,其中s長度小於1e4而且只包含數字和字母。
輸出描述:
輸出一個整數,表示s的最長重複子串長度,若不存在則輸出0.
示例:
輸入
xabcabcx
輸出
6
分析:主要用到的是字串的字尾子串,因為字尾子串能間接表示所有的子字串,java實現如下,為了解答更清楚,沒有按照題目要求輸出,這裡輸出更加詳細,也更加利於看懂。
import java.util.Scanner; public class FindRepeatedString { public static void main(String[] args){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ String s = sc.next(); String[] sub = new String[s.length()]; //儲存所求的最長子字串,可能有多個 String[] res = new String[s.length()]; //儲存所求的最長子字串的長度 int maxLength = 0; //儲存所求的最長子字串出現的個數 int maxCount = 0; //儲存字尾子串,字尾字串能間接表示所有的子字串 //每個字尾字串的所有字首字串合起來即是所有子字串 for(int i = 0; i < s.length(); i++) sub[i] = s.substring(i); //i為子字串的長度 for(int i = 1; i <= s.length()/2; i++){ //儲存每個長度的重複子字串的個數 int Count = 0; for(int j = 0; 2*i+j <= s.length(); j++){ if(sub[j].substring(0, i).equals(sub[j+i].substring(0, i))){ maxLength = 2*i; res[Count] = sub[j].substring(0, 2*i); Count ++; maxCount = Count; } } } if(maxCount == 0) System.out.println(0); else{ System.out.println(maxLength); for(int i = 0; i < maxCount; i++) System.out.println(res[i]); } } } }
下面給出C++的實現,這裡只輸出了最後一個匹配的最長的子字串。假如存在多個最長的子字串並沒有一一給出,若想像前面java實現一樣全部列出來只需稍作修改即可。
#include <iostream> #include <cstring> #include <utility> #include <string> #include <vector> using namespace std; vector<pair<int, string>> fun(const string& str) { vector<string> subs; vector<pair<int, string>> res; int len = str.size(); for (int i = 0; i < len; i++) { subs.push_back(str.substr(i)); } int length; string sub; //i為子串的長度 for (int i = 1; i <= len/2; i++) { for (int j = 0; 2*i + j <= len; j++) { if (subs[j + i].substr(0, i) == subs[j].substr(0, i)) { length = 2 * i; sub = subs[j].substr(0, i) + subs[j].substr(0, i); res.clear(); res.push_back(make_pair(length, sub)); } //res.push_back(make_pair(length, sub)); } } return res; } int main() { string str; vector<pair<int, string>> res; while (cin >> str) { res = fun(str); for (auto it = res.begin(); it != res.end(); it++) { cout << it->second << ":" << it->first << endl; } } return 0; }