大整数的加法:先对数据进行预处理是两个大整数的位数相等,位数少的那个数在高位补0,使两数的位数相等,便于计算数据的进位,只需要在函数调用的结尾检查一下最高为是否存在进位的情况,如果需要进位则只需要在最后将进位的数加入到返回值中。加法是对两个数从低位向高为相加,对每次相加的值,计算进位,取模加入到当前位置。
大整数减法:函数先对两个相等的数比较如果相等则直接返回0,然后判断两个数的大小,如果被减数大于减数则符号取负,两数交换位置;然后按照加法的做法对较小的数高位补0,最后由低位向高位按位相减。
大整数乘法:大整数的乘法与加法减法有极大的区别,乘法虽然也是按位相乘,但是不能直接简单的将字符串相拼接,例如两个两位数相乘其中在
之后如果按照加法或减法的方式直接将字符串拼接位答案肯定是不对的,所以此处应当使用按位相乘的原则
即在计算前因先对字符串转换位全0串,且长度位
。然后以两层循环对数据按位相乘并将积与
中相应位置的字符相加。遇到进位则直接与上一位的值相加,不能留到下次计算。最后需要处理的还是首位进位问题,依旧是使用一个
字符存入最后在返回时加在返回值之前即可。
#include<string.h>
#include<iostream>
std::string add(std::string s1,std::string s2) {
std::string s3;
if(s1.length()<s2.length()) {
while(s1.length()<s2.length()) {
s1="0"+s1;
}
} else {
while(s2.length()<s1.length()) {
s2="0"+s2;
}
}
int up=0;
int k;
int len=s1.length()-1;
while(len>=0) {
k=(s1.at(len) + s2.at(len) + up - '0' - '0');
up = k/10;
s3=(char)(k % 10 + '0') + s3;
len--;
}
if(up)
s3="1"+s3;
return s3;
}
std::string sub(std::string s1,std::string s2) {
if(s1==s2) {
return "0";
}
std::string s3;
bool flag=false;
if(s1.length()<s2.length() || (s1.length()==s2.length() && s1<s2)) {
std::string s=s1;
s1=s2;
s2=s;
flag=true;
} else {
s3="";
}
while(s2.length()<s1.length()) {
s2="0" + s2;
}
int k,down=0;
for(int i=s1.length()-1; i>=0; i--) {
k=s1[i] -s2[i] +down;
if(k<0) {
down=-1;
k=10+k;
} else {
down=0;
}
s3=(char)('0' + k) + s3;
}
k=0;
while(s3[k]=='0' ) {
k++;
}
s3=s3.substr(k);
if(flag)
s3="-"+s3;
return s3;
}
std::string mul(std::string s1,std::string s2) {
if(s1=="0" || s2=="0")
return "0";
if(s1=="1")
return s2;
if(s2=="1")
return s1;
std::string s3;
int len=s1.length() + s2.length() -1;
for(int i=0; i<len; i++) {
s3+="0";
}
int up=0,k;
std::string flag="";
for(int i=s1.length()-1; i>=0; i--) {
for(int j=s2.length()-1; j>=0; j--) {
k=s3[i+j]-'0' + (s1[i]-'0')*(s2[j]-'0') ;
up=k/10;
s3[i+j]=(char)(k%10+'0');
int d=1;
while(up>0) {
//首位进位
if(i==0 && j==0 && up>0) {
flag=(char)("0"+ up);
break;
}
k=(char)(s3[i+j-d]+up-'0');
up=k/10;
s3[i+j-d]=(char)(k%10+'0');
d++;
}
}
}
return flag + s3;
}