⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pollard p-1.cpp

📁 大数计算器
💻 CPP
字号:
#include<iostream>
#include<string>
using namespace std;



int Max(int x, int y)//求最大值
{
	if(x>y)
		return x;
	else return y;}

int compare(string A,string B)///比较字符串形式的数的大小
{
	int lenA,lenB;
	int dxd=0;

	lenA=A.length();
	lenB=B.length();
	if(lenA>lenB)
		dxd=1;
	if(lenA<lenB)
		dxd= -1;
	if(lenA==lenB) 
	{
		if(A>B)
			dxd= 1;
		if(A<B)
			dxd=-1;
		if(A==B)
			dxd=0;}
	return dxd;}



string Add(string a, string b)///加法
{
	int lena,lenb,round,i,j;  
	int numa[100]={0},numb[100]={0},sum[100]={0},sumrev[100]={0},carry[100]={0};//!!如计算的位数较多要修改此行中所有数组空间的大小
	string result=" ";
	lena=a.length();  //求字符串长度
	lenb=b.length();
	round=Max(lena,lenb);
	for(i=0;i<lena;i++)       //将字符串中的每个数字分别作为数组的一个元素
		numa[i]=a[lena-1-i]-48;
	for(i=0;i<lenb;i++)
		numb[i]=b[lenb-1-i]-48;
	for(i=0;i<round;i++)
	{
		sum[i]=carry[i]+numa[i]+numb[i];  //每一位的加法运算
		if(sum[i]>10)
		{carry[i+1]=1;
		sum[i]=sum[i]-10;}}
	j=0;                      //j为sum[1024]中经过计算的元素个数
	if(carry[round]=1)
        j=round;
	else j=round-1;
	

	for(i=0;i<100;i++)             //!!修改处
	{sumrev[i]=(sum[99-i]+48);}     //把数字转化成相应字符的ASCII码
  
	for(i=30-j;i<100;i++)         //!!修改处
	{result=result+char(sumrev[i]);}  //强制转换成字符串格式
	cout<<result<<endl;
	return 0;
}






string Sub(string a,string b)//减法
{
	int numa[100]={0},numb[100]={0},carry[100]={0},dif[100]={0},difrev[100]={0};//!!如计算的位数较多要修改此行中所有数组空间的大小

	int lena,lenb,round,i,j;    

	string result=" ";

	lena=a.length();
	lenb=b.length();
    round=Max(lena,lenb);
	for(i=0;i<lena;i++)
		numa[i]=a[lena-1-i]-48;
	for(i=0;i<lenb;i++)
		numb[i]=b[lenb-1-i]-48;

	for(i=0;i<round;i++)                      
	{if(lena>lenb||((lena==lenb)&&(a>b)))    //第一个数大于第二个数时
	   {if(numa[i]-numb[i]<0)
	      carry[i+1]=1;
	      dif[i]=carry[i+1]*10+numa[i]-numb[i]-carry[i];}    //每一位的减法运算
	 if(lena<lenb||((lena==lenb)&&(a<=b)))    //第一个数小等于第二个数时
	    {if(numb[i]-numa[i]<0)
   	   	  carry[i+1]=1;
	      dif[i]=carry[i+1]*10+numb[i]-numa[i]-carry[i];}}

	 for(i=0;i<100;i++)           //!!修改处
		 difrev[i]=dif[100-1-i]+48;      //数字转化为ASCII码
	 j=0;
	 while(difrev[j]==48)
         j=j+1;
	 for(i=j;i<100;i++)               //!!修改处
		 result=result+char(difrev[i]);
	 cout<<result<<endl;
	 return 0;
	}


string Div(string a,string b)//求整数商的函数
{
	string ti,mid;
	mid=a;ti="0";
	do
	{
		mid=Sub(mid,b);    //调用减法函数
		ti=Add(ti,"1");     //记录进行减法操作的次数,即为商
	}
	while(compare(mid,b)!=-1);
	return ti;
}


string Mul(string mula,string mulb)    //乘法(调用加法,错位相加)
{
     int num[200]={0};

	int lena,lenb,i,j,k;    

	string sum=" ";
	string pro=" ";
  
	lena=mula.length();
	lenb=mulb.length();
    
    if(compare(mula,mulb)>=0)         //比较哪个数位数比较多,位数小的作为循环次数
	{
	 for(i=0;i<lenb;i++)
		num[i]=mulb[lenb-1-i]-48;}

    if(compare(mula,mulb)==-1)
	{for(i=0;i<lena;i++)
       	num[i]=mula[lena-1-i]-48;}
	 
	for(i=0;i<lenb;i++)
	{
	 for(j=0;j<num[i];j++)
		 sum=Add(sum,mula);
	 for(k=0;k<i;k++)             //错位相加,高位后面前添0再相加
	 {
		 sum=sum+"0";}
		 pro=Add(sum,pro);
	}
	cout<<pro<<endl;
	return 0;
	}
	 

string Rem(string tot,string m)   //取余(多次调用减法)
{
	string remind=" ";
	string mid=" ";

	if(compare(tot,m)==1)
	{
		do
		{mid=Sub(tot,m);
		 tot=mid;}
		while(compare(tot,m)==1);
		remind=tot;
	}

	if(compare(tot,m)==0)
		remind="0";
	if(compare(tot,m)==-1)
	    remind=tot;
	cout<<remind<<endl;
	return 0;
	}


string Pow(string a,string exp)  //乘方,用平方乘的方法,调用乘法函数
{
    string result="1";
	do                              //每执行一次指数要减2
	{
		result=Mul(result,Mul(result,result));
	    exp=Sub(exp,"2");
	}
	while(compare(exp,"2")==1);
	if(compare(exp,"1")==0)
	{
		result=Mul(result,result);
		cout<<result<<endl; 
	}
	if(compare(exp,"0")==0)
		cout<<result<<endl;
    return 0;  
}

string Inv(string ini,string m)     //求逆(扩展欧几里德算法p136)
{
	string r,temp,a0,b0,q,t,t0;
	a0=ini;b0=m;t0="0";t="1";
	q=Div(a0,b0);
	r=Rem(ini,m);
    while(compare(r,"0")==1)
	{
		temp=Rem(Sub(t0,Mul(q,t)),ini);
		t0=t;
		t=temp;
		a0=b0;
		b0=r;
		q=Div(a0,b0);
		r=Sub(a0,Mul(q,b0));
	}
	if(b0!="1")
		cout<<"所求的逆不存在"<<endl;
	else return t;
}





string gcd(string a,string b)  //求最大公约数
{
	string temp=" ";
	if (compare(a,b)==-1)
	{
		temp=a;
		a=b;
		b=temp;
	}
	while(Rem(a,b)!="0")
	{
		temp=Rem(a,b);
		a=b;
		b=temp;
	}
	return b;
}

string pol(string num,string ran)   //Pollard的p-1算法
{
	string a="2";
	string j="2";
	string d=" ";
	do
	{
		a=Rem(Pow(a,j),num);
		j=Add(j,"1");
	}
	while(compare(j,ran)==-1);
	d=gcd(Sub(a,"1"),num);
	if((compare(d,"1")==-1)&&(compare(d,num))==1)
		return d;
	else cout<<"failure"<<endl;
	    return 0;
}



int main() //主程序
{
	string num,ran;
	cout<<"请输入要分解的(奇)整数n和一个预先指定的“界”B"<<endl;
	cin>>num>>ran;
	pol(num,ran);
	return 0;
}
	
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -