【暑假题目】20030703 两数相加
两数相加
题目
请使用C++计算出2^2023与3^2023的和
题目分析
首先通过题目,我们将所求的两个加数看为a,b,我们可以关注到两个点:
1.首先要解决的是两个加数的求法,这里分别有两种求法:
①通过for循环求得a,b两个加数。
②通过指数函数pow函数得到a,b两个加数。
在可以调用函数的情况下,我们应该尽力使用函数来节省我们的运算,所以在这里,我们初步定为使用pow函数来求a,b两个加数。
2.我们得到的两个加数是一个超大数字,此刻,我们面临了一个问题——超大数据的运算及其输出。
思路及其代码实现
思路一
采用指数函数pow求的两个加数后直接相加。
代码一
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
cout << pow(2, 2023) + pow(3, 2023) << endl;
return 0;
}
结果一

反思:
由于该计算超出了计算器可以表示浮点数的最大范围,即溢出,所以运行后显示inf(结果溢出),经检验后发现,如果只计算2的2023次方或者只计算3的2023次方也会结果溢出,所以,此时我们发现了本题的关键——自己实现一个无限长的数据类型。
说到无限长的数据类型我们会想到什么?
long double?不行,long double最长为16个字节,还称不上是无限长。这个时候应该想到——数组,使用数位拆分的方法,将一个超大型数据的每一位数拆分到一个足够长的数组当中去,在计算四则运算时,可以再建立一个存储进位的数组配合运算,等到输出超大型数据的时候,通过for循环进行输出。
思路二
通过循环计算两个加数,通过数位拆分将两个加数分别存入对应的数组,再建立一个进位数组进行运算
代码二
#include<iostream>
using namespace std;
int main()
{
int sum[1000], a[1000], b[1000];
int i, j, k;
for (i = 0; i < 1000; i++)//将数组中所有的数置零
{
a[i] = 0;
b[i] = 0;
}
a[0] = 1;
b[0] = 1;//避免一直循环0的次方
sum[0] = 0;//使和=0,相当于sum=0
//计算2的2023次方
for (i = 0; i < 2023; i++)//2的2023次方,故循环2023次
{
for (j = 0; j < 1000; j++)//按位数*2
{
a[j] *= 2;
}
for (j = 0; j < 1000; j++)//进位处理
{
if (a[j] > 9)//大于9的进位
{
a[j + 1]++;//最大进位为1
a[j] %= 10;//去个位的数值
}
}
}
//计算3的2023次方
for (i = 0; i < 2023; i++)//3的2023次方,故循环2023次
{
for (j = 0; j < 1000; j++)//按数*3
{
b[j] *= 3;
}
for (j = 0; j < 1000; j++)//进位处理
{
if (b[j] > 9)
{
k = b[j] / 10;//提取需十位数需进位的数字
b[j + 1] += k;
b[j] %= 10;//提取个位上的数值
}
}
}
//计算和
for (i = 0; i < 1000; i++)
{
sum[i] = a[i] + b[i];
}
for (i = 0; i < 1000; i++)
{
if (sum[i] > 9)
{
sum[i + 1]++;
sum[i] %= 10;
}
}
//输出
{
for (i = 999; i >= 0; i--)
{
cout << sum[i];
}
}
return 0;
}
结果二

反思
如果最后输出是从i=1000开始的话,会运行错误。现在结果二的答案暂时没有办法验证,寻找最新优化解法ing

浙公网安备 33010602011771号