1. 程式人生 > >字串資料結構演算法題-C++

字串資料結構演算法題-C++

1)最長不重複子串

使用stringvector<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 int
i = 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);
    }
};