lanqiaoOJ题号1516
【题⽬描述】输⼊两个整数a和b,输出这两个整数的和。a和b 都不超过100位。
本题和下⼀题介绍计算⼤数的乘法和加法。在C/C++中,⼤数的 计算⽅法称为⾼精度算法,是常⻅的考题。⽽使⽤Python和 Java代码能直接计算⼤数,不需要⽤⾼精度算法。
C++的数据类型中,最⼤的long long类型,可以声明64位的⼆ 进制数变量。此题的关键是处理⼤数的输⼊,因为整数a和b太 ⼤,⽆法将其直接赋值给C++的变量,所以不能按数字读⼊,只 能按字符读⼊。 ⼤数a⽤字符串来存储,⼀个字符存储⼀位数字,a[0]存最⾼位 数字,a[1]存次⾼位数字……a[n−1]存最低位数字,等等。计算a 加上b,先模拟每⼀位相加,再处理进位。
//1计算大整数加法
string bigint_add(string a,string b){//a,b数字字符串中的低位在前
string s,st;
int temp=0;//用来存储可能产生的进位
for(int i=a.size()-1,j=b.size()-1;i>=0||j>=0||temp>0;i--,j--){//倒序遍历,注意这里temp不为0也要循环一次
if(i>=0) temp+=a[i]-'0';
if(j>=0) temp+=b[j]-'0';
st=temp%10+'0';
s=st+s;//新加入的高位放在 s 前面,保证输出不会反
temp=temp/10;
}
// reverse(s.begin(),s.end());
return s;
}
1利用循环条件巧妙的解决了相加的大整数长度不一样的情况,另外注意temp>0也需要进入循环。
2temp赋值之前要判断一下避免越界,结果字符串记得要倒序,s=st+s可以把新获得的数直接加在前面或者出循环后倒置一下s可以起到一样的效果
lanqiaoOJ题号1515
【题⽬描述】输⼊⼀个正整数n,输出n!的值,n≤1000。
C++代码。 阶乘的值极⼤,在C++中,unsigned long long类型变量的最⼤ 值是264,⽽21!就已经⼤于264了,所以需要⽤数组来存这个 ⼤数。
这是⼀道⾼精度算法题⽬,⾼精度算法可⽤数组实现。编 程时注意以下细节。
①定义⼀个数组a[]来存放⼤数,数组的⼀个元素存放⼤数的⼀ 位数字。例如a[0]存放个位数,a[1]存放⼗位数,a[2]存放百位 数,等等。
②数组a[]需要定义成多⼤?也就是说,1000!有多少位?可以⽤ Windows⾃带的计算器直接算出来,1000! ≈4×102567。代码中 简单地定义成⼀个更⼤的数组a[10000]。
③模拟乘法运算,处理进位。 例如356×8,先计算个位的6×8,得48,其中个位的8等于 48%10=8,进位的4等于48/10=4。⻅下⾯代码中的第10~第 13⾏,这⼏⾏代码实际上是处理了两个数的乘法,请仔细分析这 ⼏⾏代码。
④按③的计算⽅法计算n!。i遍历了1~n,计算 n!。
⑤从最⾼位开始输出。先找到最⾼位,即第⼀个不等于0的数, 然后从⾼位往最低位输出。 ✧ 提示:const int a[]表示定义⼀个⼤静态数组,⼤静态 数组应该定义在全局。如果将其定义在函数内部,有些编译器会 报错。 有的读者可能知道需要考虑代码的计算复杂度问题,共循环计算了 10000×n = 10000×1000 = 1千万次,不会超时。
const int N=10000;
int a[N]={0};//在全局定义了一个大静态数组
void pow_n(int n){
a[0]=1;
int temp=0;//用来存储可能产生的进位
for(int i=1;i<=n;i++){//模拟阶乘计算
for(int j=0;j<=N;j++){
temp+=i*a[j];//以下三行实际处理了两个数的乘法
a[j]=temp%10;
temp=temp/10;
}
}
int flag=0;
for(int i=N-1;i>=0;i--){
if(a[i]!=0){//找到第一个不为0的数,开始打印
flag=i;
break;
}
}
for(int i=flag;i>=0;i--) cout<<a[i];
}
这里阶乘计算的核心在于可以直接把i和a[j]相乘,由于a是从低位到高位存储的,符合乘法的基本步骤,只要这里的结果没有超出范围,那总的结果就可以保证是对的。如果还是不清楚可以自己按照代码手算一下比较。
如144*96。那么a={441},i=96
1. 4*96=384, 4留下,temp=38
2. 4*96=384,(temp+4)%10=2,temp=(temp+4)/10=42
3.1*96=96,(temp+96)%10=8,temp=(temp+96)/10=13
由于循环从0-N-1且N足够大,保证temp可以在循环里两次赋值,留下3,1
最后倒序输出13824
验证:
1
a="123456789123456789";
b="12345678912345678912345";
//结果是12345802369134802369134
2求100的阶乘
//结果是93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000