算法之高精度(二)

本文介绍了如何处理高精度数字的输入和输出。在输入时,由于高精度数字超过了longlong的范围,因此使用字符串string来接收,然后通过将字符转化为数字并逆序存储到整数数组中。输出时,需要找到第一个非零数字的下标,从该位置开始输出直至数组开头。文章详细阐述了这一过程,并给出了示例代码。
摘要由CSDN通过智能技术生成

上一篇我们描述了:高精度是什么?如何表示高精度?
我们知道高精度是用来表示数字的。既然是数字,那么我们会想到使用数字来进行运算。比如说,加法,减法,乘法,除法等。我们依次来介绍吧。
在具体介绍加减乘除之前,我想我们还是非常有必要了解一下高精度数字的输入输出方式。

高精度数字是如何输入的?

很显然,高精度的数字是超过long long的表示范围的。因此我们并不能使用任何现有类型的变量直接存储。我们上一篇提供的方式是使用整数一维数组来存放高精度数字。输入时,我们也采用输入数组一样的方式吗?

int arr[100] ={};
for(int i = 0;i < 100; ++i)
	cin >> arr[i];

显然这种方法是不切实际的。我们并不知道数字的实际长度,并且在这个代码中,我们需要输入一百个数字才可以,还需要使用空格隔开——cin会跳过空格。你可能会直接输入5679293234813203422432这样的数字,这是不允许的。由于数字之间没有空格,程序会当成一个数字。int类型是没办法保存这么大的数字的。这会使程序出错。
解决方法就是使用字符串——string类型可以很好地解决这个问题。
string类型是C++的标准类型,它专门用来存放字符串,并且最大的优势是string类型可以自动推断字符串长度——使用size()函数就可以获得。

string s;
cin >> s;

我们可以使用56793234813203422432进行测试,答案是没问题的。字符串s中保存着这个数字。但这与我们想要的整数数组并不相同。我们需要的是一个个位数字在下标为0处的整数数组。

下标01234s.size()-3s.size()-2s.size()-1
输入的形式‘5’‘6’‘7’‘9’‘3’‘4’‘3’‘2’
想要的形式234765

这两个是由差别的。
1.输入的字符串中每一个元素都是字符
2.想要的结果应该是个位数字在下标为0的位置。
针对第一个问题,我们需要将字符转化为数字,这相对于简单。

char ch = '0';
int num = ch - '0';	//‘0’在ASCII编码中为48,字符数字减去‘0’以后,便可以得到正常的数字
//例如:'1' --> 1
ch = '1';	//ASCII码为49
num = ch - '0';	//49 - 48 = 1  得到数字1

对于第二个问题,我们就需要观察上述表格。'5'在输入形式中下标为0,而5则处于s.size()-1的位置。那么我们可以说这两个位置对应。同样地,'6'在输入形式中下标为1,而6则处于s.size()-1-1的位置——这里我故意写成两个-1,这样更好地寻找规律。
规律发现了吗?当某一个字符ch处于输入形式中下标为i的位置时,则当它转化为逆向的整数数组时,它的位置处于s.size()-1-i的位置。
有了这个规律,我们就方便多了。

string s;
cin >> s;
int sArr[100] = {};	//s字符串转换之后存放在sArr中
for(int i = 0;i < s.size(); ++i)
	sArr[i] = s[s.size() - 1 - i] - '0';	//减去'0'是转换成数字,而非字符

现在,终于处理好了输入的内容。对于sArr这样的一个数组,其中有100个元素,前面部分是我们保存的数字,后面部分(超过s.size()的部分)是0,由默认初始化得到的。

下标0123s.size()-3s.size()-2s.size()-1s.size()979899
高精度数字2347650000

现在我们要把他们输出出来。很显然,我们需要从s.size()-1的位置开始,不断向左,直到下标为0。但如果我们只能看到sArr这个数组时,我们就不能用s.size()-1进行运算了。例如下面这种情况。

#include <iostream>
using namespace std;
void add(int sArr[])
{
	//在这个函数中使用sARr数组,它是由主函数中的sArr传递进来
}
int main()
{
	string s;
	cin >> s;
	int sArr[100] = {};
	for(int i = 0;i < s.size(); ++i)
		sArr[i] = s[s.size() - 1 - i] - '0';
	add(sArr);	//调用函数
	return 0;
}

对于这种情况,我们该怎么办呢?
我们可以去前导零的方式获取。我们选择从100-1开始,这是最大的下标。当该元素为0时,我们可以一直减少下标,直到第一个非零数字出现。同样地,我们举例来看。

下标0123456
数组元素4064000

在这个表格中,就很清晰了。从下标6开始,数组元素是0。因此我们需要减少下标的值。此时,下标为5,数组元素仍为0。还需要减少下标的值。此时,下标为4,数组元素为0。继续减少下标的值。下标值为3,数组元素为4,不再是0。从这个位置开始,一直到下标为0,都是我们需要输出的内容。

//假设数组sArr已经定义好,并完成了高精度数字的转化
//int sArr[100] = {};	
int k = 100 - 1;	//100个元素,下标最大为100-1
//解释:k > 0是必须的。
//当数组中全部都是0时,我们认为这个数组保存的高精度数字是0,我们应该输出0
while(sArr[k] == 0 && k > 0)	//当sArr中下标为k时,一直减少。
	--k;

经过这样的操作,关于高精度数字的输入输出我们就介绍完成了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值