高精度算法总结(已完结)

高精度是一种计算方式,如果数据过大,会爆掉longlong,就需要用数组来模拟每一位,进行加减乘除,模拟进退位。

用高精时,要将个位赋值在数组第一个,输出时反向输出,不要弄反,不然会紊乱;

高精加

多考虑进位,这是重点;

#include<iostream>
#include<cstring>
using namespace std;
int x=0,a1[241],a2[241],b[241],o;
string s1,s2;
void ax()
{
    cin>>s1>>s2;//输入字符串
    a1[0]=s1.length();//长度
    for(int i=1;i<=a1[0];i++)
        a1[i]=s1[a1[0]-i]-48;//ASCII码值 转化
    a2[0]=s2.length();//长度
    for(int i=1;i<=a2[0];i++)
        a2[i]=s2[a2[0]-i]-48;
}
//习惯上从一开始循环,所以把个位赋值到1上,输出时反过来
void as(int a1[],int a2[])
{
    int i=1;
    while((i<=a1[0])&&(i<=a2[0]))
    {
        b[i]=a1[i]+a2[i]+x;//x是进位
        x=b[i]/10;//计算进位
        b[i]%=10;
        i++;
    }
    if(x!=0)
        b[i]=x;
    else
        i--;
    o=i;
}
int main()
{
    ax();
    as(a1,a2);
    for(int j=o;j>=1;j--)
        cout<<b[j];//反向输出
}

高精减

借位借位啊

要注意 减完之后高位可能会有0,输出前要去掉

#include<iostream>
#include<cstring>
using namespace std;
int a1[241],a2[241],b[241],o,n;
string s1,s2;
bool ad(int a1[],int a2[])//判断哪个大,用来当被减数
{
    n=1;
    if(a1[0]<a2[0]) n=0;
    if((a1[0]==a2[0])&&(s1<s2)) n=0;
    return n;
}
void ax()//输入,赋值,反向赋值
{
    cin>>s1>>s2;
    a1[0]=s1.length();
    for(int i=1;i<=a1[0];i++)
        a1[i]=s1[a1[0]-i]-48;
    a2[0]=s2.length();
    for(int i=1;i<=a2[0];i++)
        a2[i]=s2[a2[0]-i]-48;
}
void as(int a1[],int a2[])//
{
    int i=1;
    while(i<=a1[0])
    {
        if(a1[i]<a2[i])
        {
            b[i]=a1[i]+10-a2[i];
            a1[i+1]--;//借位
        }
        else
        {
            b[i]=a1[i]-a2[i];
        }
        i++;
    }
    while((b[i]==0)&&(i>1))
        i--;//减完之后,前面有可能有0,要去掉后再输出
    o=i;
}
int main()
{
    ax();
    if(ad(a1,a2)==1)
        as(a1,a2);
    else
    {
        as(a2,a1);
        cout<<"-";
    }
    for(int j=o;j>=1;j--)
        cout<<b[j];
}

高精乘

同高精加,只不过这回进位要大一点了

乘到哪一位

比如100*100=10000

最高位相乘的个位是i+j-1

再多出来的十位,算到进位中。

#include<iostream>
#include<cstring>
using namespace std;
int x=0,a1[1001],a2[1001],b[1000001],o=0;
string s1,s2;
void ax()//输入
{
    cin>>s1>>s2;
    a1[0]=s1.length();
    for(int i=1;i<=a1[0];i++)
        a1[i]=s1[a1[0]-i]-48;
    a2[0]=s2.length();
    for(int i=1;i<=a2[0];i++)
        a2[i]=s2[a2[0]-i]-48;
}
void as(int a1[],int a2[])
{
    for(int i=1;i<=a1[0];i++)//因为乘法每一位都要相乘
    {
        for(int j=1;j<=a2[0];j++)//所以两层循环
        {
            b[i+j-1]+=a1[i]*a2[j]+x;//相乘
            x=b[i+j-1]/10;//进位
            b[i+j-1]%=10;//余下的
            o=i+j-1;//总位数        
        }
        if(x!=0)
        {    
            b[o+1]=b[o+1]+x;
            x=0;
            o=o+1;
        }
    }
}
int main()
{
    ax();
    as(a1,a2);
    for(int j=o;j>=1;j--)
        cout<<b[j];
}

高精除

 经过我的悉心研究;

已经成功的搞出了高精除的算法代码

算法:

其实直接实现除法是不可能的,可以用减法来代替实现

按照除数的长度,由被除数的最高位减去这个长度,依次循环;

每一次都循环减去除数,当减到不能再减的时候,输出这个次数,就是这一位的商;

依次循环,可以得解

记住这里面有一些细节,注意减位的错误;;

在打代码的时候你会发现这个问题的

加油,高精除相比加减乘,难度上升了好多

下面,粘上代码

#include<bits/stdc++.h>
using namespace std;
string a,b;
int sa[215],sb[215],sum[215];
int camp(int x[],int x1,int y[])
{
	for(int i=x1+y[0]-1;i>=x1;i--)
		if(x[i]<y[i-x1+1])
			return 0;
		else if (x[i]>y[i-x1+1])
			return 1;
	return 2;
}
int jian1(int x1,int x2)
{
	int p=0,x[215]={};
	while(p>=0)
	{
		if(camp(sa,x1,sb)==0&&sa[x1+x2]==0)
			break;
		p++;
		for(int i=x1;i<=x1+x2-1;i++)
		{
			if(sa[i]<sb[i-x1+1])
			{
				x[i]=sa[i]+10-sb[i-x1+1];
				sa[i+1]-=1;
				continue;
			}
			else
			{
				x[i]=sa[i]-sb[i-x1+1];
				continue;
			}
		}
		for(int i=x1;i<=x1+x2-1;i++)
		{
			sa[i]=x[i];
		}
	}
	return p;
}
int jian2(int x1,int x2)
{
	int p=0,x[215]={};
	while(p>=0)
	{
		if(camp(sa,x1,sb)==0&&sa[x1+x2-1]==0)
			break;
		p++;
		for(int i=x1;i<=x1+x2-1;i++)
		{
			if(sa[i]<sb[i-x1+1])
			{
				x[i]=sa[i]+10-sb[i-x1+1];
				sa[i+1]-=1;
				continue;
			}
			else
			{
				x[i]=sa[i]-sb[i-x1+1];
				continue;
			}
		}
		for(int i=x1;i<=x1+x2-1;i++)
		{
			sa[i]=x[i];
		}
	}
	return p;
}
int main()
{
	cin>>a>>b;
	sa[0]=a.length();
	sb[0]=b.length();
	for(int i=1;i<=sa[0];i++)
		sa[i]=a[sa[0]-i]-48;
	for(int i=1;i<=sb[0];i++)
		sb[i]=b[sb[0]-i]-48;
	for(int i=sa[0]-sb[0]+1;i>=1;i--)
	{
		if(sa[i+sb[0]]!=0)
		{
			sum[i]=jian2(i,sb[0]+1);
			continue;
		}
		if(camp(sa,i,sb)==2)
		{
			//cout<<"1"<<endl;
			sum[i]=1;
			for(int j=i;j<=i+sb[0]-1;j++)
				sa[j]=0;
			continue;
		}
		if(camp(sa,i,sb)==1)
		{
			sum[i]=jian1(i,sb[0]);
			continue;
		}	
		if(camp(sa,i,sb)==0)
		{
			sum[i]=0;
			continue;
		}	
	}
	int nn=sa[0];
	while(sum[nn]==0)nn--;
	//cout<<nn<<endl;
	for(int i=nn;i>=1;i--)
		cout<<sum[i];
}

  

posted @ 2019-07-30 15:01  fengwu2005  阅读(376)  评论(2编辑  收藏  举报