一, 大数的储存
A+B的题目如果A和B在long long 范围内,那就太简单了,一般怎么会有这么简单的题呢?如果出A+B那肯定有个坑等着你里,
A和B如果是 1000位的数。
那么我们可以定义一个Int 型的整型数组,d[1000]那么这个数组中的每一位就代表了存放的整数的每一位,我们动手试一试
咦发现,这样存可以但是,算+ - 乘除的时候怎么算啊,对了,那我们就倒着存试试?动动试试,在纸上画画,好像+-乘除能算了。
在需要的时候将数组反转一下就可以了。
为了方便我们将大数存到一个结构体内,方便读取长度
struct bign{
int d[1000];
int len;
bign(){ //初始化结构体
memset(d, 0, sizeof(d));
len = 0;
}
};
这样我们再读大数的时候就可以先用字符串去读,然后再把字符串另存到bign的结构体中,用string读长的数字。
bign change(string s){
bign a;
a.len = s.length();
for(int i = 0; i < a.len; i++){
a.d[i] = s[a.len - i - 1] - '0';
}
return a;
}
如果要比较两个bign的大小简单,2种情况,长度不等,长度相1)同时,
int compare(bign a, bign b){
if(a.len > b.len) return 1; // a大
else if( a.len < b.len) return -1; //a小
else{
for(int i = a.len - 1; i >= 0; i--){
if(a.d[i] > b.d[i]) return 1;
else if(a.d[i] < b.d[i]) return -1;
}
return 0;
}
}
1)大数相加
bign add(bign a, bign b){
bign c;
int carry = 0; //carry是进位
for(int i = 0; i < a.len || i < b.len(); i++){
int temp = a.d[i] + b.d[i] + carry;
c.d[c.len++] = temp % 10;
carry = temp / 10;
}
if(carry != 0){
c.d[c.len++] = carry;
}
return c;
}
2)大数相减
bign sub(bign a,bign b){
bign c;
for(int i = 0; i < a.len || i < b.len; i++){
if(a.d[i] < b.d[i]){
a.d[i + 1]--;
a.d[i] += 10;
}
c.d[c.len++] = a.d[i] - b.d[i];
}
while(c.len - 1 >= 1 && c.d[c.len - 1] == 0){
c.len--;
}
return c;
}
3)大数相乘(高精度乘低精度)
bign multi(bign a, int b){
bign c;
int carry = 0; //进位
for(int i = 0; i < a.len; i++){
int temp = a.d[i] * b + carry;
c.d[c.len++] = temp % 10;
carry = temp / 10;
}
while(carry != 0){
c.d[c.len++] = carry % 10;
carry /= 10;
}
return c;
}
4)大数相除(高精度除低精度)
bign divide(bign a, int b, int &r){ //r为余数
bign c;
c.len = a.len;
for(int i = a.len - 1; i >= 0; i--){
r = r * 10 + a.d[i];
if(r < b) c.d[i] = 0;
else{
c.d[i] = r / b;
r = r % b;
}
}
while(c.len - 1 >= 1 && c.d[c.len - 1] == 0){
c.len--;
}
return c;
}