大数-数组实现--基础

一、高精度加法

P1601 A+B Problem(高精)

#include <iostream>
#include <cmath>
#include <cstring>

using namespace std;

const int N=505;

int a[N],b[N],c[N]; //a[0],b[0],c[0]存位数

void add()
{
    int t=0;
    int maxx=max(a[0],b[0]);
    c[0]=maxx;
    for(int i=1;i<=maxx;i++)
    {
        c[i]=a[i]+b[i]+t;
        t=c[i]/10;
        c[i]=c[i]%10;
    }
    while(t){
        c[++c[0]]=t%10;
        t=t/10;
    }
}
int main()
{
		//输入
    string s1,s2;
    cin>>s1>>s2;
    int len1=s1.size(),len2=s2.size();
    a[0]=len1;b[0]=len2;
    for(int i=len1-1;i>=0;i--) a[len1-i]=s1[i]-'0';
    for(int i=len2-1;i>=0;i--) b[len2-i]=s2[i]-'0';
		
    add();//求
    
    for(int i=c[0];i>=1;i--) cout<<c[i]; //输出
    return 0;
}

二、高精度乘法

高精度 * 高精度

P1303 A*B Problem

写法一
#include <iostream>
#include <cstring>
#include <cmath>

using namespace std;

const int N=1000010;

//c[]单步乘法 d[]存单步加法
int a[N],b[N],c[N],d[N];

//单精度 x 数 
void mul(int m)
{
    int t=0;     
    c[0]=a[0];
    for(int i=1;i<=a[0];i++){
        t=t+a[i]*m; c[i]=t%10; t=t/10;
    }
    while(t>0){
        c[++c[0]]=t%10; t=t/10;
    }
}

//start表示第几次加法
void add(int start)
{
    int t=0;
    //d存最后结果,c存中间过程
    int maxx=max(d[0],c[0]+start-1);
    d[0]=maxx;
    for(int i=start;i<=maxx;i++){
        t=d[i]+c[i-start+1]+t; d[i]=t%10; t/=10;
    }
    while(t>0){
        d[++d[0]]=t%10; t=t/10;
    }
}
//高精度 * 高精度 分解为  sum(高精度 * int) 
int main()
{
	//输入 
    string s1,s2;
    cin>>s1>>s2;
    int len1=s1.size(),len2=s2.size();
    a[0]=len1;b[0]=len2;
    for(int i=len1-1;i>=0;i--) a[len1-i]=s1[i]-'0';
    for(int i=len2-1;i>=0;i--) b[len2-i]=s2[i]-'0';
    
    //模拟人脑多位数乘法
    for(int i=1;i<=b[0];i++)
    {
        mul(b[i]); //乘法 
        add(i); //加法 参数i为第i次加法   
    }
    
    //输出 
    if(d[d[0]]==0) cout<<0;
	else 
    for(int i=d[0];i>=1;i--) cout<<d[i];
    
    return 0;
}
写法二
#include <iostream>
#include <cstring>
#include <cmath>

using namespace std;

const int N=10001;

int a[N],b[N],d[2*N];

void func()
{
	for(int i=1;i<=a[0];i++)
	{
		for(int j=1;j<=b[0];j++)
		{
			d[i+j-1]+=a[i]*b[j]; //值得注意 累加与 
		}
	}
	d[0]=a[0]+b[0]+1;
	for(int i=1;i<=a[0]+b[0];i++)
	{
		if(d[i]>=10) d[i+1]+=d[i]/10; 
		d[i]%=10;
	}
	while(d[0]>1 && !d[d[0]]) d[0]--; //保证结果至少为1位
}

int main()
{
	//输入 
    string s1,s2;
    cin>>s1>>s2;
    int len1=s1.size(),len2=s2.size();
    a[0]=len1;b[0]=len2;
    for(int i=len1-1;i>=0;i--) a[len1-i]=s1[i]-'0';
    for(int i=len2-1;i>=0;i--) b[len2-i]=s2[i]-'0';
    
	func();
	
    //输出 
    for(int i=d[0];i>=1;i--) cout<<d[i];
    
    return 0; 
	
 } 

可去练习
https://www.luogu.com.cn/problem/P1249

高精度 * 单精度

P1009 [NOIP1998 普及组] 阶乘之和

#include <iostream>
#include <cstring>
#include <cmath>

using namespace std;

const int N=200;

//由于是阶乘 则a[]存单步乘法 d[] 存结果
int a[N],d[N];

void mul(int m)
{
    int t=0;
    for(int i=1;i<=a[0];i++)
    {
        t=a[i]*m+t; a[i]=t%10; t=t/10;
    }
    while(t) {
        a[++a[0]]=t%10; t=t/10;
    }
}

void add()
{
    int t=0;
    int maxx=max(a[0],d[0]);
    d[0]=maxx; //更新d的位数
    for(int i=1;i<=maxx;i++)
    {
        t+=a[i]+d[i];
        d[i]=t%10;
        t=t/10;
    }
    while(t){
        d[++d[0]]=t%10;
        t=t/10;
    }
}

int main()
{
    int n;
    cin>>n;
    //不要忘记初始化
    a[0]=1;a[1]=1;
    d[0]=1;d[1]=0;
    
    for(int i=1;i<=n;i++)
    {
        mul(i); add();
    }
   
    for(int i=d[0];i>=1;i--) cout<<d[i];
    return 0;
}

三、高精度减法

高精度 - 高精度

前提:a>b

#include <iostream>
#include <cstring>
#include <cmath>

using namespace std;

const int N=1000010;
int a[N],b[N],d[N]; //使a>b

void sub()
{
    int t=0;
    d[0]=a[0]+1;
    for(int i=1;i<=a[0];i++)
    {
        t=a[i]-b[i]-t;
        d[i]=(t+10)%10;
        if(t<0) t=1; else t=0;
    }
    while(d[0]>1 && d[d[0]]==0) d[0]--;
}

int main()
{
	string s1,s2;
	cin>>s1>>s2;
	
	a[0]=s1.size(); b[0]=s2.size();
	for(int i=0;i<a[0];i++) a[a[0]-i]=s1[i]-'0'; 
	for(int i=0;i<b[0];i++) b[b[0]-i]=s2[i]-'0';

	sub();
	for(int i=d[0];i>=1;i--) cout<<d[i];    
    return 0;
}

四、高精度除法

高精度 / 单精度

#include  <iostream>
#include <cstring>
#include <cmath>

using namespace std;

const int N=1000010;

int a[N],d[N];

int  div(int m)
{
	int t=0;
	d[0]=a[0];
	for(int i=a[0];i>=1;i--)
	{
		t=t*10+a[i];
		if(t>=m) d[i]=t/m;
		t=t%m;
	}
	while(d[0]>1 && d[d[0]]==0) d[0]--;
	return t;
}

int main()
{
	string s1;
	cin>>s1;
	int b;
	cin>>b;
	a[0]=s1.size();
	for(int i=0;i<a[0];i++) a[a[0]-i]=s1[i]-'0';
	
	int r=0;//存余数 
	r=div(b);
	
	cout<<s1<<"/"<<b<<"=";
	for(int i=d[0];i>=1;i--) cout<<d[i];
	cout<<"..."<<r;
	
	return 0;
 } 

高精度 / 高精度

#include<iostream>
#include <cmath>
#include<cstring>
using namespace std;

const int N=1000010;

int a[N],b[N],d[N],temp[N];

void init(int a[]){
    string s; 
	cin>>s;
    a[0]=s.size();
    for(int i=0;i<a[0];i++)  a[a[0]-i]=s[i]-'0';
}

//返回值为1则a>b ;为0则a==b ;为-1则a<b 
int cmp(int a[],int b[]){
     if(a[0]>b[0])  return 1;
     if(a[0]<b[0])  return-1;
     for(int i=a[0];i>0;i--){ 
         if(a[i]>b[i]) return 1;
         if(a[i]<b[i]) return -1; 
     }
    return 0;
}

void sub(int a[],int b[]){
    int t=0; 
    for(int i=1;i<=a[0];i++){
    	t=a[i]-b[i]-t; 
    	a[i]=(t+10)%10;
        t= t<0 ?1:0;
    }
    while(a[0]>1 && a[a[0]]==0) a[0]--;
}

//start 为添加的0的数目 
void numCpy(int arr1[],int arr2[],int start){
	
	arr2[0]=arr1[0]+start;
	//拷贝到高位 
    for(int i=1;i<=arr1[0];i++) arr2[i+start]=arr1[i];
}

//模拟人脑除法
void div(int a[],int b[],int d[]){
	
    d[0]=a[0]-b[0]+1; //结果的位数   
    for(int i=d[0];i>=1;i--){  
    
    	//单步初始化 
        memset(temp,0,sizeof(temp));
        numCpy(b,temp,i-1);//这里的参数(i-1)是在b数后面添加(i-1)个0,然后赋值给temp 
        
        //单步操作 
        while(cmp(a,temp)>=0){
            d[i]++;
            sub(a,temp);
        }
    }
    
    while(d[0]>1 && d[d[0]]==0) d[0]--;
}

int main(){
    init(a); init(b);
    
	div(a,b,d);
    
    for(int i=d[0];i>=1;i--) cout<<d[i];
	cout<<"..."; 
    for(int i=a[0];i>=1;i--) cout<<a[i]; 
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值