51NOD-1005 大数加法

题目传送门

/*
	我的代码水平可以说是很烂了。。。
	又臭又长的AC代码
*/
#include <iostream>
#include <stdio.h>
#include <string>
#include <algorithm>
#define MAXN 10010//数字的最大长度
using namespace std;
//char s1[MAXN], s2[MAXN];
string s1, s2;
int len1 = 0;//用来计算两个数串的长度
int len2 = 0;
int num1[MAXN], num2[MAXN], number[MAXN];
void add(string x, string y)
{//处理同号数据
	for (int i = x.length() - 1; i >= 0; i--)
		if (x[i] != '-')
			num1[len1++] = x[i] - '0';
	for (int i = y.length() - 1; i >= 0; i--)
		if (y[i] != '-')
			num2[len2++] = y[i] - '0';
	//把字符全部转化为数字,个位数在num1[0]
	for (int i = 0; i < max(len1, len2); i++)
	{//模拟竖式计算
		number[i] += num1[i] + num2[i];//同位相加
		if (number[i] >= 10)
		{//进位
			number[i] -= 10;
			number[i + 1]++;
		}
	}
}
void subtract(string x, string y)
{//异号数据处理起来比同号数据复杂好多
	for (int i = x.length() - 1; i >= 0; i--)
		if (x[i] != '-')
			num1[len1++] = x[i] - '0';
	for (int i = y.length() - 1; i >= 0; i--)
		if (y[i] != '-')
			num2[len2++] = y[i] - '0';
	//把除了负号以为的转化为数字
	//接下来要判断两个数字谁更大,因为我们在竖式计算的时候都才用大减小
	if (len1 > len2)
	{//谁长谁肯定多大
		for (int i = 0; i < len1; i++)
		{
			number[i] += num1[i] - num2[i];
			if (number[i] < 0)
			{
				number[i] += 10;
				number[i + 1]--;
			}
		}
	}
	else if (len2>len1)
	{
		for (int i = 0; i < len2; i++)
		{
			number[i] += num2[i] - num1[i];
			if (number[i] < 0)
			{
				number[i] += 10;
				number[i + 1]--;
			}
		}
	}
	else
	{//如果两个长度相等,就从最高位开始,往后比较到个位
		bool flag;
		//如果num1大就是true,num2大就是false
		for (int i = len1-1; i >= 0; i--)//
			if (num1[i] > num2[i])
			{
				flag = true;
				break;
			}
			else
			{
				flag = false;
				break;
			}
		if (flag)
		{//谁大减谁
			for (int i = 0; i < len1; i++)
			{
				number[i] += num1[i] - num2[i];
				if (number[i] < 0)
				{
					number[i] += 10;
					number[i + 1]--;
				}
			}
		}
		else
		{
			for (int i = 0; i < len2; i++)
			{
				number[i] += num2[i] - num1[i];
				if (number[i] < 0)
				{
					number[i] += 10;
					number[i + 1]--;
				}
			}
		}
	}
}
int main(void)
{
	cin >> s1 >> s2;
	if (s1[0] == '-'&&s2[0] == '-')
	{//都是负数属于同号处理
		add(s1, s2);
		printf("-");//在最开始加上负号
		if (number[max(len1, len2)])
			printf("%d", number[max(len1, len2)]);
		for (int i = max(len1, len2) - 1; i >= 0; i--)
			printf("%d", number[i]);
	}
	//接下来分两种情况都是属于异号,分别是第一个数是负数和第二个数是负数的情况
	else if (s1[0] == '-')
	{
		bool ok = false;//用以判断两者会不会相等

		if (s1.length() - 1 > s2.length())
			printf("-");//通过比较正负数的长度,来知道两个数的大小,判断是否在前面加上符号
		else if (s1.length() - 1 == s2.length())
		{//两个数长度相等
			for (int i = 0; i < s1.length(); i++)
				if (s1[i + 1] > s2[i])//从最高位开始比较,这里注意s1[0]是负号不是数字
				{//负数比较大
					ok = true;
					putchar('-');
					break;
				}
				else if (s1[i + 1] < s2[i])
				{
					ok = true;
					break;
				}
		}
		else//只要两者不相等都是true
			ok = true;
		subtract(s1, s2);
		if (!ok)
			printf("0");
		else
		{
			int down;
			for (down = max(len1, len2) - 1; number[down] == 0; down--);
			//上面这两步是为了去除前导零,也就是整数前面没有用的0
			for (int i = down; i >= 0; i--)
				printf("%d", number[i]);
		}
	}
	else if (s2[0] == '-')
	{//和上一种情况雷同,不多做阐述
		bool ok = false;

		if (s1.length() < s2.length() - 1)
			printf("-");
		else if (s1.length() == s2.length() - 1)
		{
			for (int i = 0; i < s1.length(); i++)
				if (s1[i] < s2[i + 1])
				{
					ok = true;
					putchar('-');
					break;
				}
				else if (s1[i] > s2[i + 1])
				{
					ok = true;
					break;
				}
		}
		else
			ok = true;
		subtract(s2, s1);
		if (!ok)
			printf("0");
		else
		{
			int down;
			for (down = max(len1, len2) - 1; number[down] == 0; down--);
			for (int i = down; i >= 0; i--)
				printf("%d", number[i]);
		}
	}
	else
	{//相加就不用多说
		add(s1, s2);
		//printf("-");
		if (number[max(len1, len2)])
			printf("%d", number[max(len1, len2)]);
		for (int i = max(len1, len2) - 1; i >= 0; i--)
			printf("%d", number[i]);
	}
	//system("pause");

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值