字串資料結構演算法題-C++
1)最長不重複子串
使用string
和vector<string>
string FindLongestNonRepeatSubstring(string str) { if (str.empty()) return ""; string tmp;//存放臨時不重複的子串 vector<string> svec;//存放所有不重複的子串 int start = 0;//標記每次開始查詢子串的下標 int pos = -1; //查詢當前字元在子串中的位置下標 tmp.push_back(str[0]); for (unsigned inti = 1; i < str.size(); ++i) { pos = tmp.find(str[i]); if (pos == -1) { tmp.push_back(str[i]); } else { svec.push_back(tmp); tmp.clear(); start = start + pos + 1; i = start; tmp.push_back(str[i]); } } vector<string>::iterator it = svec.begin(); int maxIndex = 0; for (unsigned int i = 1; i < svec.size(); ++i) { if (svec[i].size() > svec[maxIndex].size()) { maxIndex = i; } } return svec[maxIndex]; } --------------------- 原文:https://blog.csdn.net/yishizuofei/article/details/79059844
2)字串的全排列
1 class Solution { 2 public: 3 void dfs(string s,int begin,vector<string> &result){ 4 if(begin==s.size()-1) 5 result.push_back(s); 6 for(int i=begin;i<s.size();i++){ 7 if(i!=begin&&s[i]==s[begin]) 8 continue; 9 swap(s[i],s[begin]); 10 dfs(s,begin+1,result); 11 swap(s[i],s[begin]); 12 } 13 } 14 15 vector<string> Permutation(string str) { 16 vector<string> result; 17 dfs(str,0,result); 18 sort(result.begin(),result.end());//按照字典序輸出 19 return result; 20 } 21 };
3)判斷字串A是否是字串B的子串(字串模式匹配)- 簡單演算法(BF)
KMP字串模式匹配演算法是在一個字串中定位另一個串的高效演算法,時間複雜度為O(m+n)。簡單匹配演算法的時間複雜度為O(m*n)。
int BF(char *A, char *B) { int i = 0, j = 0; while(A[i] != '\0') { if(B[j] != '\0') { if(A[i] == B[j]) { i ++; j ++; } else { i = i - j +1; j = 0; } } if(j == strlen(B)) { return i - j; } } return -1; }
4)字串中的最長迴文子串
用動態規劃方法解(原文:https://blog.csdn.net/qq_26286193/article/details/80291718)
假設字串s的長度為length,建立一個length*length的狀態轉移矩陣dp。
dp[i][j]表示“以s[i]開始s[j]結尾的迴文串的長度。如果這個字串不是迴文串,讓dp[i][j]=0”。顯然,j>=i,只需往dp填j>=i的部分即可。
dp[i][j]的遞推公式可以這麼表述:
(1)首先對dp的對角線元素初始化為1,也就是當i==j時,dp[i][j]=1。
這很顯然,每個單獨的字元其實就是個長度為1的迴文串。
(2)當j-i==1:
若s[i]==s[j],則dp[i][j]=2;否則dp[i][j]=0。
解釋:當j-i==1時,若s[i]==s[j],則s[i]和s[j]可以組成一個長度為2的迴文串。若s[i]!=s[j],顯然他們不可能組成迴文串,dp[i][j]=0。
(3)當j-i>=2:
若s[i]==s[j]:若dp[i+1][j-1]>0,則dp[i][j]= dp[i + 1][j - 1] + 2;否則dp[i][j]= 0;
若s[i]!=s[j]:dp[i][j]=0。
解釋:如果s[i]==s[j],表明這個子串有可能是迴文串。當去頭去尾後它是迴文串時,就可以在去頭去尾的那個迴文串長度基礎上+2,得到它的長度。如果去頭去尾後不是迴文串,那這個子串一定不是迴文串,迴文串長度只能是0。
若s[i]!=s[j],顯然他們不可能組成迴文串,dp[i][j]=0。
只需找到dp[i][j]的最大元素和它對應的i和j就可以得到結果“s中最長迴文子串”。
class Solution { public: // 最長迴文串,使用dp string longestPalindrome(string str) { int n = str.length(); if(n==0) return ""; bool dp[n][n]; fill_n(&dp[0][0],n*n,false); int left=0,right=0,maxLen = 0; for(int j=0;j<n;j++) { dp[j][j] = true; for(int i=0;i<j;i++) { dp[i][j] = (str[i] == str[j] && (j-i < 2 || dp[i+1][j-1])); if(dp[i][j] && (j-i+1 > maxLen)) { left = i; right = j; maxLen = j-i+1; } } } return str.substr(left,right-left+1); } };