KMP算法在圓周率中查找生日


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 ---


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM