1.關於本文ios
本文中全部的代碼都爲實現一個目標,即:算法
寫一個函數:從字符串s中找到字符串a第一次出現的位置,不存在則返回-1數組
2.方法1:樸素的字符串搜索算法函數
用一個循環來找出全部有效位移ui
#include<iostream> #include<string> using namespace std; //函數:找出字符串s中第一次出現字符串a的位置(樸素算法) int IndexOf_01(string s,string a) { bool isMatch; for(int i = 0; i <= s.length() - a.length(); i++) { isMatch = true; for(int j = 0; j < a.length(); j++) { if(s[i + j] != a[j]) { isMatch = false; break; } } if(isMatch) { return i; } } return -1; } int main() { string s = "the quick brown fox jumped over the lazy dogs"; cout << s << endl; cout << "index of \"the\": " << IndexOf_01(s, "the") << endl; cout << "index of \"quick\": " << IndexOf_01(s, "quick") << endl; cout << "index of \"dogs\": " << IndexOf_01(s, "dogs") << endl; cout << "index of \"cats\": " << IndexOf_01(s, "cats") << endl; return 0; }
3.方法2spa
本方法受到了 Rabin-Karp 啓發,至關於對原算法作了以下修改code
窗口長度:m=a.length(),第一次匹配規則:t=t[0]+t[1]+...+t[t.length()-1],模p=max字符串
對於字符串s的每個長度爲m的子串,若是該子串全部字符的ASCII碼和與目標字符串相同,則逐個比對該子串與目標字符串是否相同,不然跳過。若子串與目標字符串相同,則認爲匹配,不然繼續向後搜索。get
#include<iostream> #include<string> using namespace std; //函數:找出字符串s中第一次出現字符串a的位置(受到Rabin-Karp算法啓發) int IndexOf_02(string s,string a) { //s的長度應大於a的長度 if(s.length() < a.length()) { return -1; } //計算第一組數字和 int target = 0, current = 0; for(int i = 0; i < a.length(); i++) { target += a[i]; current += s[i]; } //開始匹配 bool isMatch; for(int i = 0; i <= s.length() - a.length(); ) { //若是全部字符的數字和相同,則進一步比較 if(current == target) { isMatch = true; for(int j = 0; j < a.length(); j++) { if(s[i + j] != a[j]) { isMatch = false; break; } } if(isMatch) { return i; } } //計算下一組字符的數字和 current -= s[i]; current += s[i++ + a.length()]; } return -1; } int main() { string s = "the quick brown fox jumped over the lazy dogs"; cout << s << endl; cout << "index of \"the\": " << IndexOf_02(s, "the") << endl; cout << "index of \"quick\": " << IndexOf_02(s, "quick") << endl; cout << "index of \"dogs\": " << IndexOf_02(s, "dogs") << endl; cout << "index of \"cats\": " << IndexOf_02(s, "cats") << endl; return 0; }
4.Knuth-Morris-Pratt(KMP)算法string
KMP算法,函數ComputePrefix用於計算輔助數組
#include<iostream> #include<string> using namespace std; //計算前綴 int* ComputePrefix(string a) { int *array = new int[a.length() + 1]; int x = 0; array[0] = 0; for(int i = 1; i < a.length(); i++) { if(a[i] == a[x]) { array[i] = array[i - 1] + 1; x++; } else { array[i] = 0; x = 0; } } return array; } //函數:找出字符串s中第一次出現字符串a的位置(KMP算法) int IndexOf_KMP(string s, string a) { //計算前綴 int *perfix = new int[a.length()]; perfix = ComputePrefix(a); //判斷a在s中第一次出現的位置 int x = 0, y = 0; while(x < s.length()) { if(s[x + y] == a[y]) { y++; if(y == a.length()) { return x; } } else { if(y == 0) { x++; } else { x += (y - perfix[y - 1]); } y = 0; } } return -1; } int main() { string tests = "ababaabababcabab"; cout << tests << endl; string testa0 = "ababa"; cout << testa0 << ": " << IndexOf_KMP(tests, testa0) << endl; string testa1 = "ababc"; cout << testa1 << ": " << IndexOf_KMP(tests, testa1) << endl; string testa2 = "cabab"; cout << testa2 << ": " << IndexOf_KMP(tests, testa2) << endl; string testa3 = "aaaaa"; cout << testa3 << ": " << IndexOf_KMP(tests, testa3) << endl; return 0; }