【暑假题目】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

 
posted @ 2023-07-06 13:20  山远尽成云  阅读(101)  评论(0)    收藏  举报