第一种逻辑比较直接但是过程略显冗杂的方法
思想
- 由于最长整形无法存入大数,所以选用字符数组来存放输入的数字,输入之后会像这样:
999999 ——first_add
88888 ——second_add
-
用两个变量记录两个加数的长度,比较并记录最大长度
-
直接从两个加数的个位开始向前遍历相加,并将结果退一位记录在另一个字符数组中,比如这样:
代码拆分
由于这种方法重点在于模拟竖式加法,且在两个加数不等长的讨论中,思路是一样的,所以只对其中一种情况做详解。
for (i = 0; i < len_max; i++) {
if (i < len_second) {
//较短加数还没遍历完时
j = first_add[len_first - i - 1] + second_add[len_second - i - 1] - 96 + flag;
//直接将上一位的进位结果与当前位相加,但是记得flag要初始化为0
if (j >= 10) {
flag = 1;
j %= 10;
}
else {
/*这个else必须存在,不然会导致进位结果过度顺延,因为当前位的结果
要顺延至下一位,所以不能用每一轮循环后重置来代替这个else的作用*/
flag = 0;
}
}
else {
//较短加数遍历完了,只用计算进位和较长加数
j = first_add[len_first - i - 1] + flag;
if (j >= 10) {
flag = 1;
j %= 10;
}
else {
flag = 0;
}
}
result[len_max - i] = j + 48;
//要记得把结果转化为字符再存入字符数组里面
}
result[len_max + 1] = '\0';
//记得字符串最后要加终止符,不然后面用 %s输出会有乱码
完整代码
#include<stdio.h>
#include<string.h>
//假设数字最大位数时是200位
int main(void) {
char first_add[200];
char second_add[200];
char result[201];
int len_first = 0, len_second = 0, len_max = 0;
int i = 0, flag = 0,j = 0;//flag作为进位标志,j储存每一位加法和
scanf("%s", first_add);
scanf("%s", second_add);
len_first = strlen(first_add);
len_second = strlen(second_add);
if (len_first > len_second) {
//如果第一个加数比第二个大
len_max = len_first;
for (i = 0; i < len_max; i++) {
if (i < len_second) {
//较短加数还没遍历完时
j = first_add[len_first - i - 1] + second_add[len_second - i - 1] - 96 + flag;
if (j >= 10) {
flag = 1;
j %= 10;
}
else {
flag = 0;
}
}
else {
//较短加数遍历完了,只用计算进位和较长加数
j = first_add[len_first - i - 1] + flag;
if (j >= 10) {
flag = 1;
j %= 10;
}
else {
flag = 0;
}
}
result[len_max - i] = j + 48;
//要记得把结果转化为字符再存入字符数组里面
}
result[len_max + 1] = '\0';
if (flag) {
result[0] = '1';
printf("%s", &result[0]);
}
else {
printf("%s", &result[1]);
}
}
else {
//以下的思路与上面是一样的,只是由于 first_add和 second_add的长度不一样,在计算时做了区分
len_max = len_second;
for (i = 0; i < len_max; i++) {
if (i < len_first) {
j = first_add[len_first - i - 1] + second_add[len_second - i - 1] - 96 + flag;
if (j >= 10) {
flag = 1;
j %= 10;
}
else {
flag = 0;
}
}
else {
j = second_add[len_second - i - 1] + flag;
if (j >= 10) {
flag = 1;
j %= 10;
}
else {
flag = 0;
}
}
result[len_max - i] = j + 48;
}
result[len_max + 1] = '\0';
if (flag) {
result[0] = '1';
printf("%s", &result[0]);
}
else {
printf("%s", &result[1]);
}
}
return 0;
}
}
第二种逻辑更为直接但是步骤非常多的方法
思想
- 由于最长整形无法存入大数,所以选用字符数组来存放输入的数字,输入之后会像这样:
999999 ——first_add
88888 ——second_add
- 考虑到进位的问题,所以将字符数组向右对齐并退一位,达到这样的效果:
0999999 ——first_add
0088888 ——second_add
- 考虑进位,相加,于是结果就变成这样:
0999999 ——first_add
- 0088888 ——second_add
-------------
1088887 ——result
代码拆分
- 把两个字符串右对齐
//无论是不是最长字符串,都要往后挪一位,为结果的进位腾出位置
//first_add
for (i = 0; i <= len_max; i++) {
if (i < len_first) {
//这里不能取等号,否则会导致下一步赋值出现问题
first_add[len_max - i] = first_add[len_first - i - 1];
/*这里相当于把原字符串的倒数第i个字符,赋给最长字符串从后往前数第i个位置,
由于原字符串最后一位是'\0'所以还要减一才能够取到有效字符*/
}
else {
first_add[len_max - i] = '0';
//将后移之后的字符串,前面补足0
}
}
first_add[len_max + 1] = '\0';
//second_add
for (i = 0; i <= len_max; i++) {
if (i < len_second) {
second_add[len_max - i] = second_add[len_second - i - 1];
}
else {
second_add[len_max - i] = '0';
}
}
second_add[len_max + 1] = '\0';
- 模拟竖式加法运算
(悄咪咪说一下,数字’0’的ASCII码是48)
for (i = len_max; i >= 0; i--) {
j = (first_add[i] - 48) + (second_add[i] - 48) + flag;
//注意flag在这步之前一定要初始化成0,否则个位相加就会出错
if (j >= 10) {
flag = 1;
j %= 10;
}
else {
flag = 0;
}
result[i] = j + 48;
}
- 输出结果
result[len_max +1] = '\0';
//记得要补一个终止符,不然不会自动停喔
if ('0' == result[0]) {
printf("%s", &result[1]);
}
else {
printf("%s", &result[0]);
}
//通过判断最大位是否有进位,决定从第几个字符开始输出
完整代码
#include<stdio.h>
#include<string.h>
int main(void) {
char first_add[201];
char second_add[201];
char result[201];
//考虑到进位的问题,要比加数中最大的还要多一位
int len_first = 0, len_second = 0, len_max = 0;
int i = 0, flag = 0,j = 0;//flag作为进位标志,j储存每一位加法和
scanf("%s", first_add);
scanf("%s", second_add);
len_first = strlen(first_add);
len_second = strlen(second_add);
len_max = len_first > len_second ? len_first : len_second;
//无论是不是最长字符串,都要往后挪一位,为结果的进位腾出位置
//first_add
for (i = 0; i <= len_max; i++) {
if (i < len_first) {
//没有等于号
first_add[len_max - i] = first_add[len_first - i-1];
}
else {
first_add[len_max - i] = '0';
}
}
first_add[len_max + 1] = '\0';
//second_add
for (i = 0; i <= len_max; i++) {
if (i < len_second) {
second_add[len_max - i] = second_add[len_second - i-1];
}
else {
second_add[len_max - i] = '0';
}
}
second_add[len_max + 1] = '\0';
//从max位开始向前做加法
for (i = len_max; i >= 0; i--) {
j = (first_add[i] - 48) + (second_add[i] - 48) + flag;
if (j >= 10) {
flag = 1;
j %= 10;
}
else {
flag = 0;
}
result[i] = j + 48;
}
result[len_max +1] = '\0';
if ('0' == result[0]) {
printf("%s", &result[1]);
}
else {
printf("%s", &result[0]);
}
}