KMP算法不多說,算是經典算法里難啃的硬骨頭。
理論上圓周率小數點后10e位包含了任意8位數的組合,即所有人的生日。存放圓周率的文件用y-cruncher軟件生成,這個軟件可以生成包含pi在內的各種常數,還可以進行壓力測試。

軟件運行界面如圖,生成10e位數字會提示內存不夠,一般情況5000w就夠用了。生成的文件在軟件子目錄下,可以轉移到代碼運行目錄,也可以直接輸入文件路徑。
代碼如下:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int Index_KMP(string S, string T, int pos, int next[]) {
/* 利用模式串T的next函數求T在主串S中的第pos個
字符之后的位置的KMP算法。其中,T非空,
1≤pos≤StrLength(S)*/
int i = pos;
int j = 1;
while (i <= S.size() && j <= T.size()) { //0下標存儲字符串長度
if (j == 0 || S[i - 1] == T[j - 1]) { ++i; ++j; } // 繼續比較后繼字符
else j = next[j]; // 模式串向右移動
}
if (j > T.size())
return i-T.size(); // 匹配成功
else
return 0;
} // Index_KMP
void get_next(string T, int next[]) {
// 求模式串T的next函數值並存入數組next
int i = 1;
next[1] = 0;
int j = 0;
while (i < T.size()) {
if (j == 0 || T[i - 1] == T[j - 1])
{
++i;
++j;
next[i] = j;
}
else j = next[j];
}
} // get_next
int main () {
int next[9],pos;
ifstream infile;
string birth,S;
//cout << "請輸入文件路徑:";
//cin >> sdir;
cout << "請輸入8位生日:";
cin >> birth;
get_next(birth, next);
infile.open("Pi.dat"); //讀取文件
if(!infile.is_open())
return 0;
infile >> S;
pos = Index_KMP(S, birth, 0, next);
if(pos != 0)
cout << "匹配成功:匹配串中第" << pos << "個字符為模式串開始" << endl;
else
cout << "查詢無結果,請更新文件!" <<endl;
infile.close();
return 0;
}
這里我直接用一個string接受了文件內容,如果文件內容很大的話建議分多次讀取。

--- end ---
