Java教程

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

本文主要是介绍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 ---

这篇关于KMP算法在圆周率中查找生日的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!