我是靠谱客的博主 爱笑芝麻,最近开发中收集的这篇文章主要介绍大数加减,较大数阶乘(高精度),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

    • 1.大整数加法
        • a.纯STL(string)实现:
        • b.数组实现:
        • c.数组模块化实现:
        • d.若改题为:两数的最高位都不是0:
    • 2.大整数减法
        • a.数组实现:
        • b.数组模块化实现:
    • 3.求10000以内n的阶乘
        • a.数组实现:

1.大整数加法

10:大整数加法

描述:
        求两个不超过200位的非负整数的和。
输入:
        有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。
输出:
        一行,即相加后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。
样例输入:
        22222222222222222222
        33333333333333333333
样例输出:
        55555555555555555555

a.纯STL(string)实现:

#include <bits/stdc++.h>
using namespace std;
string add(string a,string b)
{
    a = a.substr(a.find_first_not_of('0'));//去掉前导0并复制该串重新赋值给a
    b = b.substr(b.find_first_not_of('0'));
    reverse(a.begin(), a.end());//低位求和
    reverse(b.begin(), b.end());
    int lenA = a.length(),lenB = b.length();
    int len = max(lenA,lenB)+1;//求和后的长度
    string ans(len,'0');//字符全都是'0'且长度是len的字符串
    for (int i = 0; i < lenA; ++i){ans[i] = a[i];}//拷贝a字符串到答案串
    for (int i = 0,t=0; i < len; ++i)
    {
        if (i<lenB) t+= (b[i]-'0')+(ans[i]-'0');//复合的赋值运算符优先级很低,逗号运算符最低 
        else t+=(ans[i]-'0');
        ans[i] = (t%10+'0');
        t/=10;
    }
    reverse(ans.begin(), ans.end());//翻转回来
    return ans.substr(ans.find_first_not_of('0'));//这里可能求和后没有进位所以要去掉翻转之后的前导0
}
int main(int argc, char const *argv[])
{
    string a,b;
    cin>>a>>b;
    //这里要特判0
    if (a=="0") cout<<b<<endl;
    else if (b=="0") cout<<a<<endl;
    else cout<<add(a,b)<<endl;
    return 0;
}

b.数组实现:

#include<bits/stdc++.h>
using namespace std;
string a2,b2;
int a[200],b[200],c[200];
int main()
{
    int di,x=0;//数字位数:Number of digits
    cin>>a2>>b2;
    int n=a2.length(),m=b2.length();//取长度 
    for(int i=0;i<n;i++){ a[n-i-1]=a2[i]-'0'; }//倒序转整
    for(int i=0;i<m;i++){ b[m-i-1]=b2[i]-'0'; }
    di=max(m,n);
    for(int i=0;i<di;i++)
    {
        c[i]=(b[i]+a[i]+x)%10;
        x=(b[i]+a[i]+x)/10;//进位 
    }
    if(x>0){ c[di++]=x; }
    for(;c[di-1]==0&&di>1;)  di--;//去前导零
    for(int i=di-1;i>=0;i--){printf("%d",c[i]); }
    return 0;
}

c.数组模块化实现:

#include<bits/stdc++.h>
using namespace std;
string sum_bigint(string a2,string b2){
    //适用于不超过200位的非负整数(可以有多余的前导0)相加 
    int a[200],b[200],c[200];
    memset(a,0,sizeof(a));//不写会WA 
    memset(b,0,sizeof(b));
    memset(c,0,sizeof(c));
    int n=a2.length(),m=b2.length();//取长度
    for(int i=0;i<n;i++){ a[n-i-1]=a2[i]-'0'; }//倒序转整
    for(int i=0;i<m;i++){ b[m-i-1]=b2[i]-'0'; }
    int di=max(m,n),x=0;//数字位数:Number of digits
    for(int i=0;i<di;i++)
    {
        c[i]=(b[i]+a[i]+x)%10;
        x=(b[i]+a[i]+x)/10;//进位
    }
    if(x>0){ c[di++]=x; }//判最高位 
    for(; c[di-1]==0&&di>1 ;)  di--;//去前导零
    string s;
    for(int i=di-1;i>=0;i--) {s+= c[i]+'0'; }//注意c是整形数组 
    return s;
}
int main()
{
    string a,b;
    cin>>a>>b;
    cout<<sum_bigint(a,b);
    return 0;
}

d.若改题为:两数的最高位都不是0:

#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<b;i++)
using namespace std;
int main(){
    string s,s1,s2;  cin>>s1>>s2;
    reverse(s1.begin(),s1.end());
    reverse(s2.begin(),s2.end());
    int len=max(s1.length(),s2.length());
    string s3;fo(i,0,100)s3+='0';s1+=s3;s2+=s3;//增加位数 
    int t,temp=0;
    fo(i,0,len){//用数组没事,用string要减(或加)'0' 
        t=s1[i]-'0'+s2[i]-'0'+temp;
        s+=t%10+'0';
        temp=t/10;      
    }
    while(temp){s+=temp%10+'0';temp/=10;}
    reverse(s.begin(),s.end());
    cout<<s;
    return 0;
}

2.大整数减法

11:大整数减法:

描述:
        求两个大的正整数相减的差。
输入:
        共2行,第1行是被减数a,第2行是减数b(a > b)。每个大整数不超过200位,不会有多余的前导零。
输出:
        一行,即所求的差。
样例输入:
        9999999999999999999999999999999999999
        9999999999999
样例输出:
        9999999999999999999999990000000000000

a.数组实现:

#include<bits/stdc++.h>
using namespace std;
string a,b;
int x[999],y[999],A,B,i,k,m;
main(){
    cin>>a>>b;
    A=a.length(),B=b.length();
    for(i=0;i<A;i++)x[A-i]=a[i]-'0';//不用reverse了
    for(i=0;i<B;i++)y[B-i]=b[i]-48;//小知识:48就是'0' 
    while(++k<=A || k<=B){ //注意||自左向右 
        if(x[k]<y[k])
            x[k]+=10,x[k+1]--;//逗号表达式 
        x[k]-=y[k];
    }
    while(x[k]==0&&k>1) k--;//去除多余的前导零
    for(i=k;i>0;i--)cout<<x[i];
}

b.数组模块化实现:

#include<bits/stdc++.h>
using namespace std;
string sub_bigint(string a,string b){
    //subtraction:减法//a为被减数,b为减数, 可以有多余的前导零
    int x[999],y[999],i,k=0;
    memset(x,0,sizeof(x));
    memset(y,0,sizeof(y));
    int A=a.length(),B=b.length();
    for(i=0;i<A;i++)x[A-i]=a[i]-'0';//不用reverse了
    for(i=0;i<B;i++)y[B-i]=b[i]-48;//小知识:48就是'0' 
    while(++k<=A || k<=B){ //注意||自左向右 
        if(x[k]<y[k])
            x[k]+=10,x[k+1]--;//逗号表达式 
        x[k]-=y[k];
    }
    while(x[k]==0&&k>1) k--;//去除多余的前导零
    string s;
    for(i=k;i>0;i--) s+= x[i]+'0';
    return s;
}
main(){
    string a,b;
    cin>>a>>b;
    cout<<sub_bigint(a,b); 
}

3.求10000以内n的阶乘

14:求10000以内n的阶乘

描述:
	求10000以内n的阶乘。		
输入:
        只有一行输入,整数n(0<=n<=10000)。
输出:
        一行,即n!的值。
样例输入:
        100
样例输出:
	933262154439441526816992.........(太多了,省略一下)

a.数组实现:

//先默认结果有且仅有一位,是1 
#include<stdio.h>
int a[40000];
int main() 
{
    int jw=0,w=1,n,t;
    a[0]=1;//注意 
    scanf("%d",&n);
    for(int i=1;i<=n;i++)//遍历每个乘数 
    {
        for(int j=0;j<w;j++)
        {
            t=a[j]*i+jw;
            a[j]=t%10;
            jw=t/10;            
        }//对每一位做乘法 
        while(jw)
        {
            a[w++]=jw%10;
            jw/=10;
        }//进位 
    }
    for(int i=w-1;i>=0;i--){printf("%d",a[i]);}//逆序输出 
    return 0; 
}

最后

以上就是爱笑芝麻为你收集整理的大数加减,较大数阶乘(高精度)的全部内容,希望文章能够帮你解决大数加减,较大数阶乘(高精度)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部