模拟:超大整数加减法

无数次面对这样的问题,两个长度是几千甚至上万的字符串相加或相减,输出结果。这次专门练习写一遍。

校赛ACM时候就卡在这种题上了,不然就能AC七道题了!!

        1.两个大数相加的函数比相减的简单些,不用考虑结果会不会是负数的问题。接收到两个字符串和一个要存储和的目标字符串,先反转两个字符串,后以较长字符串为目标,挨个加到存储和的字符串。当当前长度小于短串的时候,每一位再加上短串的对应位,当前位相加后超过9则进位。长度超出短串后,加上长串对应位的同时也要判断当前位有没有超过9。结束后注意判断一下和有没有超出长串的长度(可能会进位),用字符串结束标志'\0'结束目标字符串即可,反转目标字符串后结束函数。

void BigNumAdd(char* a, char* b, char* str)
{
	if (strlen(a)<strlen(b))
	{
		BigNumAdd(b, a, str);
		return;
	}
	reverse(a), reverse(b);
	for (int i = 0; i <= strlen(a); i++)
		str[i] = '0';
	for (int i = 0; i<strlen(a); i++)
	{
		str[i] += a[i] - '0';
		if (i<strlen(b))
		{
			int num = str[i] - '0' + b[i] - '0';
			if (num>9)
			{
				str[i] = num - 10 + '0';
				str[i + 1]++;
			}
			else
			{
				str[i] = num + '0';
			}
		}
		else
		{
			if (str[i]>'9')
			{
				str[i] -= 10;
				str[i + 1]++;
			}
		}
	}
	if (str[strlen(a)] > '0')
		str[strlen(a) + 1] = 0;
	else
		str[strlen(a)] = 0;
	reverse(str);
}

a和b是相加的两个字符串,str是目标字符串(存储和)

void reverse(char* str)
{
	int ind = strlen(str) - 1;
	int ins = 0;
	while (ins<ind)
	{
		char ch = str[ind];
		str[ind] = str[ins];
		str[ins] = ch;
		ind--, ins++;
	}
	return;
}

这是用到的反转字符串函数,头尾开始交换,直到中间碰头结束。

        2.两个大数相减先考虑的是两数大小问题,只有大数减小数才不会出现负数的情况。我先判断两字符串长度,如果两字符串长度相同再逐位判断大小,长度不满足被减数大于减数则交换被减数和减数,并用返回值来表示此次减法运算是否结果为负。减数和被减数相同则直接赋值目标字符串0,并结束函数。

        满足被减数大于减数后,反转两字符串。和大数相加的思路相同,从低位开始逐位判断相减后有没有小于0,如果小于则将高位减一。没有减数后也要逐位判断有没有出现小于0的数。最后要注意的是,高位可能若干位因为被减或借位成0,所以遍历找到第一个不为0的高位。将上一位赋值'\0'结束字符串,反转后完成大数相减。

int BigNumSub(char*a, char* b, char* str)
{
	int i = 0;
	int j = 0;
	while (1)
	{
		if (strlen(a)<strlen(b))
		{
			BigNumSub(b, a, str);
			return 1;
		}
		if (strlen(a)>strlen(b))
			break;
		else
		{
			if (a[i]<b[j])
			{
				BigNumSub(b, a, str);
				return 1;
			}
			if (a[i]>b[j])
				break;
			else
			{
				if (i == strlen(a))
				{
					str[0] = '0';
					str[1] = 0;
					return 0;
				}
				i++, j++;
			}
		}
	}
	reverse(a), reverse(b);
	for (int i = 0; i <= strlen(a); i++)
		str[i] = '0';
	for (int i = 0; i<strlen(a); i++)
	{
		str[i] += a[i] - '0';
		if (i<strlen(b))
		{
			int num = str[i] - b[i];
			if (num<0)
			{
				str[i] = num + 10 + '0';
				str[i + 1]--;
			}
			else
			{
				str[i] = num + '0';
			}
		}
		else
		{
			if (str[i]<'0')
			{
				str[i] = '9';
				str[i + 1]--;
			}
		}
	}
	int st = strlen(a) - 1;
	while (str[st] == '0')
		st--;
	str[st + 1] = 0;
	reverse(str);
	return 0;
}

a是被减数字符串,b是减数字符串,str是目标字符串。返回值非0表示结果为负数,为0则为正数或0。

所用到的反转字符串函数同上。


之后再写大数乘法、除法、开方?

猜你喜欢

转载自blog.csdn.net/belous_zxy/article/details/80331402
今日推荐