加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

模版--大数加减乘除

发布时间:2021-05-29 12:00:54 所属栏目:大数据 来源:网络整理
导读:/* 因为计算大数除法时需要用到乘法和减法, 但是不指定字符串长度的乘法和减法不容易用字符数组表示, 所以这里就没写用字符数组计算的大数除法。o(╯□╰)o */ /***********大数加减乘/仅限正整数***************/ //加法测试:HDU 1002 //减法测试:百练O

/* 因为计算大数除法时需要用到乘法和减法, 但是不指定字符串长度的乘法和减法不容易用字符数组表示, 所以这里就没写用字符数组计算的大数除法。o(╯□╰)o */

/***********大数加减乘/仅限正整数***************/
//加法测试:HDU 1002
//减法测试:百练OJ 2736
//乘法测试:百练OJ 2980

#include <cstdio>
#include <cstring>
#include <malloc.h>
#include <algorithm>
#include <climits>
#include <cmath>
using namespace std;
const int MAX_N=100010;

char a[MAX_N],b[MAX_N],ope[10],ans[MAX_N];
int data[MAX_N];

void Big_Plus()
{
    int lena=strlen(a),lenb=strlen(b);
    if(lena>=lenb){//a位数比b多 
        for(int i=lenb;i>=0;i--)//遍历b中所有元素 
            b[i+(lena-lenb)]=b[i];//数字后移,使末位与a对其 
        for(int i=0;i<lena-lenb;i++)//将数字b中高位上多出来的部分遍历赋0 
            b[i]='0';
    } else{
        for(int i=lena;i>=0;i--)
            a[i+(lenb-lena)]=a[i];
        for(int i=0;i<lenb-lena;i++)
            a[i]='0';
    }
    int carry=0,lenans=max(lena,lenb);
    ans[lenans]='';//添加结束符
    int tmp=lenans-1;
    while(tmp>=0){//循环条件;a和b对应位上数字加完 
        int x=a[tmp]-'0';
        int y=b[tmp]-'0';
        int z=x+y+carry;
        if(z>=10) carry=z/10;
        else carry=0;
        z%=10;
        ans[tmp]=z+'0';
        tmp--;
    }
    if(carry){//最高位计算完仍有进位
        for(int i=lenans;i>=0;i--)//lenans是考虑到结束符
            ans[i+1]=ans[i];    //后移 
        ans[0]=carry+'0';   //最高位为carry
    }
}

void Big_Sub()
{
    int lena=strlen(a);//ca为a的长度 
    int lenb=strlen(b);//cb为b的长度 
    if(lena>lenb||lena==lenb&&strcmp(a,b)>=0){ //a的长度大于b或a的长度等于b且字符串a>=b,结果为正
        int i,j;
        for(i=lena-1,j=lenb-1;j>=0;i--,j--) //遍历a与b公共长度个字符数字 
            a[i]-=(b[j]-'0');   //计算其结果 
        for(i=lena-1;i>=0;i--){     //遍历a的所有下标 
            if(a[i]<'0'){   //如果当前下标对应值小于0,则借位操作 
                a[i]+=10;   //当前值加10 
                a[i-1]--;   //高位减1 
            }
        }
        i=0;
        //去除前导0
        while(a[i]=='0'&&i<lena-1) i++;
        strcpy(ans,a+i);//将结果复制到ans数组
    } else {//类似上面部分 
        int i,j=lenb-1;i>=0;i--,j--)
            b[j]-=(a[i]-'0');
        for(j=lenb-1;j>=0;j--){
            if(b[j]<'0'){
                b[j]+=10;
                b[j-1]--;   
            }
        }
        j=0;
        while(b[j]=='0'&&j<lenb-1) j++;
        ans[0]='-';//运算结果为负 
        strcpy(ans+1,b+j);
    }
}

void Big_Mul()
{
    int lena=strlen(a),lenb=strlen(b); 
    int lenans=lena+lenb-1;
    for(int i=0;i<=(lena-1)/2;i++) swap(a[i],a[lena-1-i]); //数组逆置
    for(int i=0;i<=(lenb-1)/2;i++) swap(b[i],b[lenb-1-i]);
    memset(data,0,sizeof(data));
    for(int i=0;i<lena;i++){
        for(int j=0;j<lenb;j++)
            data[i+j]+=(a[i]-'0')*(b[j]-'0');   //模拟乘法,计算每一位
    }
    int carry=0;    
    for(int i=0;i<lenans;i++){
        int tmp=data[i]+carry;
        carry=tmp/10;
        data[i]=tmp%10;
    }
    while(carry){
        data[lenans++]=carry%10;
        carry/=10;
    }
    while(data[lenans-1]==0&&lenans>1) lenans--;
    for(int i=0;i<=lenans-1;i++) ans[i]=data[lenans-1-i]+'0';
    ans[lenans]='';   //添加结束符
}

int main()
{
    //freopen("BigIntin.txt","r",stdin);
    //输入:运算数和运算符之间有空格
    while(~scanf("%s%s%s",a,ope,b))
    {
        printf("%s%s%s=",b);
        if(ope[0]=='+'){
            Big_Plus();
        }else if(ope[0]=='-'){
            Big_Sub();
        }else if(ope[0]=='*'){
            Big_Mul();
        }
        puts(ans);
    }
    return 0;
}
/********大数加减乘除C++string类实现**********/
//运算数仅限正整数

//加法测试:HDU 1002
//减法测试:百练OJ 2736
//乘法测试:百练OJ 2980
//除法测试:百练OJ 2737

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <climits>
#include <string>
using namespace std;

//string比较函数:相等返回0,str1>str2返回1,str1<str2返回-1.
int Compare(string str1,string str2)
{
    if(str1.length() > str2.length()) return 1;
    else if(str1.length() < str2.length()) return -1;
    else return str1.compare(str2);
}

string Big_Plus(string str1,string str2)
{
    string ans;
    int len1=str1.length();
    int len2=str2.length();
    //将长度较小的前面补0,使两个string长度相同
    if(len1<len2){
        for(int i=1;i<=len2-len1;i++){
            str1="0"+str1;
        }
    }else {
        for(int i=1;i<=len1-len2;i++){
            str2="0"+str2;
        }
    }
    int len=max(len1,len2);
    int carry=0;
    for(int i=len-1;i>=0;i--){
        int tmp=str1[i]-'0'+str2[i]-'0'+carry;
        carry=tmp/10;
        tmp%=10;
        ans=char(tmp+'0')+ans;
    }
    if(carry) ans=char(carry+'0')+ans;
    return ans;
}

//支持大数减小数
string Big_Sub(string str1,string str2)
{
    string ans;
    int carry=0;
    int difference=str1.length()-str2.length();//长度差
    for(int i=str2.length()-1;i>=0;i--){
        if(str1[difference+i]<str2[i]+carry){
            ans=char(str1[difference+i]+10-str2[i]-carry+'0')+ans;
            carry=1;
        }else {
            ans=char(str1[difference+i]-str2[i]-carry+'0')+ans;
            carry=0;
        }
    }
    for(int i=difference-1;i>=0;i--){
        if(str1[i]-carry>='0'){
            ans=char(str1[i]-carry)+ans;
            carry=0;
        }else {
            ans=char(str1[i]-carry+10)+ans;
            carry=1;
        }
    }
    //去除前导0
    ans.erase(0,ans.find_first_not_of('0'));
    if(ans.empty()) ans="0";
    return ans;
}

string Big_Mul(string str1,string str2)
{
    string ans;
    int len1=str1.length();
    int len2=str2.length();
    for(int i=len2-1;i>=0;i--){
        string tmpstr="";
        int data=str2[i]-'0';
        int carry=0;
        if(data!=0){
            for(int j=1;j<=len2-1-i;j++){
                tmpstr+="0"; 
            }
            for(int j=len1-1;j>=0;j--){
                int t=data*(str1[j]-'0')+carry;
                carry=t/10;
                t%=10;
                tmpstr=char(t+'0')+tmpstr;
            }
            if(carry!=0) tmpstr=char(carry+'0')+tmpstr;
        }
        ans=Big_Plus(ans,tmpstr);
    }
    ans.erase(0,ans.find_first_not_of('0'));
    if(ans.empty()) ans="0";
    return ans;
}

//正数相除,商为quotient,余数为residue

void Big_Div(string str1,string str2,string& quotient,string& residue)
{
    quotient=residue="";//商和余数清空
    if(str2=="0"){//;判断除数是否为0
        quotient=residue="ERROR";
        return;
    }
    if(str1=="0"){//判断被除数是否为0
        quotient=residue="0";
        return;
    }
    int res=Compare(str1,str2);
    if(res<0){//被除数小于除数
        quotient="0";
        residue=str1;
        return;
    }else if(res==0){
        quotient="1";
        residue="0";
        return ;
    }else {
        int len1=str1.length();
        int len2=str2.length();
        string tmpstr;
        tmpstr.append(str1,len2-1);//将str1的前len2位赋给tmpstr
        for(int i=len2-1;i<len1;i++){
            tmpstr=tmpstr+str1[i];//被除数新补充一位
            tmpstr.erase(0,tmpstr.find_first_not_of('0'));//去除前导0
            if(tmpstr.empty()) tmpstr="0";
            for(char ch='9';ch>='0';ch--){//试商
                string tmp,ans;
                tmp=tmp+ch;
                ans=Big_Mul(str2,tmp);//计算乘积
                if(Compare(ans,tmpstr)<=0){//试商成功
                    quotient=quotient+ch;
                    tmpstr=Big_Sub(tmpstr,ans);//减掉乘积
                    break;
                }
            }
        }
        residue=tmpstr;
    }
    quotient.erase(0,quotient.find_first_not_of('0'));
    if(quotient.empty()) quotient="0";
}

int main()
{
    //freopen("BigIntin.txt",stdin);
    string str1,str2,str3,str4;
    while(cin>>str1>>str2){
        cout<<Big_Plus(str1,str2)<<endl;
        cout<<Big_Sub(str1,str2)<<endl;
        cout<<Big_Mul(str1,str2)<<endl;
        Big_Div(str1,str4);
        cout<<"商:"<<str3<<" "<<"余数:"<<str4<<endl;
    }
    return 0;
}

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!