1.题面
题目来源计蒜客T1098。
求两个不超过
200
200
200位的非负整数的和。
输入格式
有两行,每行是一个不超过
200
200
200位的非负整数,可能有多余的前导
0
0
0。
输出格式
一行,即相加后的结果。结果里不能有多余的前导
0
0
0,即如果结果为
342
342
342,那么就不能输出为
0342
0342
0342。
输出时每行末尾的多余空格,不影响答案正确性。
样例输入
22222222222222222222222
33333333333333333333333
样例输出
55555555555555555555555
2.分析
(以下是本人的分析及代码,不是最优的代码)
(1)从控制台获取输入的数字,使用cin.getline()
方法
char* snum1 = new char[300]; //存放第一行输入的数
char* snum2 = new char[300]; //存放第二行输入的数
cin.getline(snum1, 300);
cin.getline(snum2, 300);
(2)将获取的字符串转为int
类型数组
- 获取输入数字的位数
len1
存放第一个输入数字的位数,len2
存放第二个输入数字的位数。
(以第一个输入的数字为例,第二个输入的数字类似。)
int len1 = 0; //存放第一个输入数字的位数
char* p = snum1;
while (*p != '\0')
{
len1++;
p++;
}
- 转换为
int
类型数组
该数组的特点是:输入数字的高位在数组中的下标也为高位,输入数字的低位在数组中的下标也为低位。例:输入数字为12345
,则转换为的整型数组为{5, 4, 3, 2, 1}
。
num1
存放第一个输入数字,num2
存放第二个输入数字,均为整型指针int*
。
(以第一个输入的数字为例,第二个输入的数字类似。)
int* num1 = new int[len1]; //存放第一个输入的数字
for (int i = 0; i < len1; i++)
{
switch (snum1[i])
{
case '0':
num1[len1 - 1 - i] = 0;
break;
case '1':
num1[len1 - 1 - i] = 1;
break;
case '2':
num1[len1 - 1 - i] = 2;
break;
case '3':
num1[len1 - 1 - i] = 3;
break;
case '4':
num1[len1 - 1 - i] = 4;
break;
case '5':
num1[len1 - 1 - i] = 5;
break;
case '6':
num1[len1 - 1 - i] = 6;
break;
case '7':
num1[len1 - 1 - i] = 7;
break;
case '8':
num1[len1 - 1 - i] = 8;
break;
case '9':
num1[len1 - 1 - i] = 9;
break;
default:
break;
}
}
(3)进行加法运算
由于两个整数相加,其和的位数最多为max{len1, len2} + 1
。
设len = max{len1, len2}
,num
存放两个整数相加的和。
int len = len1 > len2 ? len1 : len2;
int* num = new int[len + 1];
设c
表示低位进位,则num1[i] + num2[i] + c
的个位作为num[i]
的值,十位作为第i + 1
位的低位进位。
int c = 0;
for (int i = 0; i < len; i++)
{
if (i < len1 && i < len2)
{
int s = c + num1[i] + num2[i];
num[i] = s % 10;
c = s / 10;
}
else
{
if (len == len1)
{
int s = c + num1[i];
num[i] = s % 10;
c = s / 10;
}
else
{
int s = c + num2[i];
num[i] = s % 10;
c = s / 10;
}
}
}
num[len] = c;
这样,两个整数相加的和就存放在num
数组中了。
(4)去除前导
0
0
0
num
中存放的结果可能存在前导
0
0
0,需要去除。
int* q = num + len;
while (*q == 0 && q != num)
{
q--;
}
此时,指针q
指向的是结果中的最高非零位。对于num
全为0
的情况也适用,即通过条件q != num
来判断。
最后就可以打印出结果了。
while (q != num)
{
cout << *q;
q--;
}
cout << *num;
(5)删除申请的动态内存
3.代码
整体代码如下:
#include <iostream>
using namespace std;
int main()
{
char* snum1 = new char[300];
char* snum2 = new char[300];
cin.getline(snum1, 300);
cin.getline(snum2, 300);
int len1 = 0;
int len2 = 0;
char* p = snum1;
while (*p != '\0')
{
len1++;
p++;
}
p = snum2;
while (*p != '\0')
{
len2++;
p++;
}
p = NULL;
int* num1 = new int[len1];
int* num2 = new int[len2];
for (int i = 0; i < len1; i++)
{
switch (snum1[i])
{
case '0':
num1[len1 - 1 - i] = 0;
break;
case '1':
num1[len1 - 1 - i] = 1;
break;
case '2':
num1[len1 - 1 - i] = 2;
break;
case '3':
num1[len1 - 1 - i] = 3;
break;
case '4':
num1[len1 - 1 - i] = 4;
break;
case '5':
num1[len1 - 1 - i] = 5;
break;
case '6':
num1[len1 - 1 - i] = 6;
break;
case '7':
num1[len1 - 1 - i] = 7;
break;
case '8':
num1[len1 - 1 - i] = 8;
break;
case '9':
num1[len1 - 1 - i] = 9;
break;
default:
break;
}
}
for (int i = 0; i < len2; i++)
{
switch (snum2[i])
{
case '0':
num2[len2 - 1 - i] = 0;
break;
case '1':
num2[len2 - 1 - i] = 1;
break;
case '2':
num2[len2 - 1 - i] = 2;
break;
case '3':
num2[len2 - 1 - i] = 3;
break;
case '4':
num2[len2 - 1 - i] = 4;
break;
case '5':
num2[len2 - 1 - i] = 5;
break;
case '6':
num2[len2 - 1 - i] = 6;
break;
case '7':
num2[len2 - 1 - i] = 7;
break;
case '8':
num2[len2 - 1 - i] = 8;
break;
case '9':
num2[len2 - 1 - i] = 9;
break;
default:
break;
}
}
int len = (len1 > len2 ? len1 : len2);
int* num = new int[len + 1];
int c = 0;
for (int i = 0; i < len; i++)
{
if (i < len1 && i < len2)
{
int s = c + num1[i] + num2[i];
num[i] = s % 10;
c = s / 10;
}
else
{
if (len == len1)
{
int s = c + num1[i];
num[i] = s % 10;
c = s / 10;
}
else
{
int s = c + num2[i];
num[i] = s % 10;
c = s / 10;
}
}
}
num[len] = c;
int* q = num + len;
while (*q == 0 && q != num)
{
q--;
}
while (q != num)
{
cout << *q;
q--;
}
cout << *num;
delete[] snum1, snum2, num1, num2, num;
snum1 = snum2 = NULL;
num1 = num2 = num = q = NULL;
return 0;
}