字串 演算法總結

2021-08-19 04:45:44 字數 4092 閱讀 2071

1.字串的複製

char *scopy(char *str1,const char *str2);  

int main()

char *scopy(char *str1,const char *str2)

str1[j]='\0';

return str1;

}

2.字串的回文

判斷字串是否是回文

#include #include using namespace std;

int main()

}if(flag) cout<<"yes!"《找字串中最長回文子串(馬拉車)

計算字串中最長回文子串,我們使用了一下5種方法:

1)暴力求解,不用將奇數字串和偶數字串分開討論,只需要前向和後向確定元素的工作同時進行,通過不斷從左邊縮小字串來求出其回文子串,進而得到最長的回文子串;

2)中心拓展法:遍歷每個字元,然後以該字元為中心向左右兩邊進行拓展,從左向右移動,就可以獲取最長的回文子串的,但是需要注意奇數和偶數回文子串的不同,需要進行不同的處理;

3)中心拓展發的優化:區分技術和偶數顯得程式顯得非常冗餘,為什麼不將原來的字串進行乙個變形,使得程式只用針對奇數或者偶數型別進行處理呢?我們這兒選擇將原始的字串變形為奇數字串進行處理;

4)動態規劃:因為我們知道最長回文字串的子串一定為回文串,因此我們可以利用動態規劃法則進行求解,利用map[i][j]判斷從i到j是否為回文陣列,如果s[i-1]==s[j+1],就可以在o(1)的時間內判斷[i-1,j+1]是否為回文了;

#include #include #include #include #include using namespace std;

/*針對求解最長回文子串,我們分別嘗試了5種方法進行求解:

1)暴力演算法,時間複雜度非常高;

2)分類暴力演算法,分別針對奇數和偶數進行分析;

3)分類暴力演算法優化,通過構建新的字串避免進行奇偶分析;

4)動態規劃法則進行求解,通過回文淄川的子類一定是回文子串,利用動態規劃演算法進行求解;

5)利用最常間的manacher演算法進行求解

*/ //暴力演算法

int longest_ror_string(string s,vector& v)

else

flag = true;

vec_temp = vec;

break;

}ki++;

kj--;

}if (flag == true) break;

}if (max < count)

}cout << max << endl;

return max;

}//分類暴力演算法

string longestpalindrome(string s)

}//計算偶數最長回文字串

j = i;

z = i + 1;

while ((z < s.length()) && (j >= 0) && (s[z] == s[j]))

z++;

j--;}}

if (max1 + 1 > max2) result = s.substr(idx1 - max1 / 2, max1 + 1);

else result = s.substr(idx2 - max2 / 2 + 1, max2);

return result;

}//分類暴力演算法優化

//通過改造字串使得程式不用區分奇偶了

//aba改造為#a#b#a#,abba改造為#a#b#b#a#,即處理的都是奇數啦!

string longestpalindrome_better(string s)

temp[j++] = '#';

temp[j] = '\0';

for (int i = 0; i < 2 * s.size() + 1; i++)}}

return s.substr((idx - max) / 2, max);

}//動態規劃

string longestpalindrome_dp(string s);

//初始化奇數的回文子串

for (int i = 0; i < len; i++)

//初始化偶數的回文子串

for (int i = 0; i < len - 1; i++)

}for (int plen = 3; plen <= len; plen++)}}

return s.substr(idx, max);

}//馬拉車

string longestpalindrome_manacher(string s)

int *p = new int[temp.length()];

memset(p, 0, sizeof(p));

//max記錄的是最長回文子串的長度,idx記錄的是最長回文串的中心位置

int max = 0, idx = 0;

//mx記錄i之前的最長回文子串延伸到最右邊的位置,id記錄該字串的中心位置

int mx = 0, id = 0;

//因為第乙個是'$'字元,所以不用計算它的p值

for (int i = 1; i < temp.length(); i++)

else

while (i + p[i] < temp.length() && temp[i - p[i]] == temp[i + p[i]])

if (i + p[i] > mx)}}

max--;

delete p;

return s.substr((idx - max) / 2, max);

}int main()

給定乙個字串s,你可以從中刪除一些字元,使得剩下的串是乙個回文串。如何刪除才能使得回文串最長呢?也就是需要刪除最少的字元個數,輸出需要刪除的字元個數。
#include #include #include #include using namespace std;

int helper(string s)

else if (c[i-1][j] >= c[i][j-1])

else if (c[i - 1][j] < c[i][j - 1])

}//列印

/*for (int i = size, j = size; i >= 1 && j >= 1;)

else if (c[i][j - 1] >= c[i - 1][j])

else if (c[i][j - 1] < c[i - 1][j])}*/

return size - c[size][size];

}int main()

3.括號的匹配

這是用「棧」這種資料結構來解決的一道典型問題

。它的特點可以簡單的概括為「後進先出」。

#include#includechar s[20003];  

int main()

if(top==0) printf("yes\n");

else printf("no\n");

} return 0;

}

括號的匹配問題的優化:

可以用陣列代替棧的資料結構

#include #include using namespace std;  

// 判斷字元是不是左括號型別

bool isleft(char c)

// 判斷右括號與左括號是否匹配

bool ismatch(char right, char left)

if (right == ']')

if (right == '}')

} // 判斷字串是否匹配

bool matching(char* s)

else

cs.pop();

} ++s;

} if (!cs.empty())

return true;

}

字串演算法總結

易犯錯誤 1 a c a 輸入的是大寫 a c減成了小寫 a 導致陣列的下標越界,程式執行時發生段錯誤 2 由字串轉換為數字時只有當字元是一位的時候才可以直接 0 如 11 就不可以直接 0 3 由數字轉化為字串時也要注意是否是一位的,如11就不可以直接用 0 轉化 4 審題不細,漏輸出,漏條件 問...

字串演算法總結 模板

目錄 kmp模式匹配演算法 manacher最長回文子串演算法 給出長度n的主串和長度m的模式串進行模式匹配,複雜度o n m 預處理出失敗指標 最長公共前字尾 進行平攤為o 1 的轉移 int nxt maxn void build next char s if s j 1 s i nxt i j...

字串演算法題總結

字串題做了將近乙個月,部落格上整理的20道和筆記中整理的十幾道,接近40道了,不總結一下整體的思路,大腦是一片混亂的。基礎題 考查對字串類相關的操作,其中重點掌握切片 連線和內建方法。子串題 子串題盡是困難題,但是同時也是非常經典的一類題目,需要好好掌握。常用的方法和技巧有滑動視窗 python c...