模版--大数加减乘除
发布时间:2021-05-30 02:33:22 所属栏目:大数据 来源:网络整理
导读:/* 因为计算大数除法时需要用到乘法和减法, 但是不指定字符串长度的乘法和减法不容易用字符数组表示, 所以这里就没写用字符数组计算的大数除法。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; } (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |