要求
利用圆周率生成函数生成圆周率,并在此基础上实现KMP算法查找自己生日
方法
这里使用的是梅钦公式(Machin formula):
\frac{\pi}{4}=4\arctan\funcapply\frac{1}{5}-\arctan\funcapply\frac{1}{239}
或者写为:
\begin{matrix}\arccot\funcapply(x)=\frac{1}{x}-\frac{1}{3x3}+\frac{1}{5x5}-\frac{1}{7x^7}+\ldots\\pi=4\times(4\times\arccot\funcapply(5)-\arccot\funcapply(239))\\end{matrix}
代码
#include <iostream>
using namespace std;
//long long wei=30000000;
long long wei=400000;
char strp[10]="020020308",mypi[400010];
int n=8;
int ne[10];
long long idx=2;
int getpi(){
long long a[2]={956,80},b[2]={57121,25},i=0,j,k,p,q,r,s=2,t,u,v,M=10000;
long long N=wei/4+3;
long long *pi=new long long[N],*e=new long long[N];
while(i<N)pi[i++]=0;
while(--s+1)
{
for(*e=a[k=s],i=N;--i;)e[i]=0;
for(q=1;j=i-1,i<N;e[i]?0:++i,q+=2,k=!k)
for(r=v=0;++j<N;pi[j]+=k?u:-u)u=(t=v*M+(e[j]=(p=r*M+e[j])/b[s]))/q,r=p%b[s],v=t%q;
}
while(--i)(pi[i]=(t=pi[i]+s)%M)<0?pi[i]+=M,s=t/M-1:s=t/M;
for(;++i<N-2;){
mypi[idx]= '0'+(pi[i]/1000);
mypi[idx+1]='0'+(pi[i]/100%10);
mypi[idx+2]='0'+(pi[i]/10%10);
mypi[idx+3]='0'+pi[i]%10;
idx+=4;
}
return 0;
}
int main(){
mypi[1]='3';
getpi();
cout<<"已计算出圆周率的前"<<wei<<"位\n";
for (int i = 2, j = 0; i <= n; i ++ )
{
while (j && strp[i] != strp[j + 1]) j = ne[j];
if (strp[i] == strp[j + 1]) j ++ ;
ne[i] = j;
}
int xx=0;
for (int i = 1, j = 0; i <= 30000000; i ++ )
{
while (j && mypi[i] != strp[j + 1]) j = ne[j];
if (mypi[i] == strp[j + 1]) j ++ ;
if (j == n)
{
printf("在圆周率中找到了生日:20020308,从小数点后第 %d 位开始", i - n);
j = ne[j];
break;
}
xx=max(xx,j);
}
return 0;
}