实现两个大整数的相加,首先应该排除直接使用int和long long的方法,这些方法很容易溢出,这里为了方便(是否可以使用更精简的结构存储?)采用char来存储整数,整体思路如下:

1. 对于整数n和m的字符串形式,按照数组索引的从大到小累加计算,直接将结果存储到对应的result字符串中,处理完毕后再将result逆序输出,需考虑0和-的输出情况;

2. 考虑到有负号的情况,一开始就需要判断负号字符,这里将(-,-)和(+,+)统一当成相加操作然后都是负号的话在结尾补上负号,对于(+,-)和(-,+)统一处理成(大-小)的形式然后在结尾补负号;比如对于20-500转换成-(-20+500),对于-500+20准换成-(500-20)。

3. 这里需要使用标志位nTake记录是否进位或借位;

4. 还要考虑是否有异常字符出现,使用全局变量gInvalid记录有无异常。

 #include<stdio.h>
#include<string.h> #define Joshua_OJ bool gInvalid = false; // 0: equal, -1: n less m, 1: n bigger m
int AbsIsEqual(char* n, char* m, int n_start, int n_end, int m_start, int m_end)
{
if ((n_end - n_start) > (m_end - m_start)) return ;
else if ((n_end - n_start) < (m_end - m_start)) return -;
else
{
int i = n_start;
int j = m_start;
while (i <= n_end && j <= m_end)
{
if (n[i] > m[j]) return ;
else if (n[i] < m[j]) return -;
++i;
++j;
}
}
return ;
} void BigNumberAdd(char* n, char* m, char* result)
{
gInvalid = false; if (n == NULL || m == NULL)
{
gInvalid = true;
return;
} int n_index = strlen(n) - ;
int m_index = strlen(m) - ; // 负数特别处理
int n_start = ;
int m_start = ;
int n_signed = ;
int m_signed = ;
if (n[] == '-')
{
n_start = ;
n_signed = -;
}
if (m[] == '-')
{
m_start = ;
m_signed = -;
}
// 如果只有一个负数,转换为大数减小数再取负号,这样方便异号借位相减
bool isResetPosNeg = false;
if (n_signed == && m_signed == -)
{
int tag = AbsIsEqual(n, m, n_start, n_index, m_start, m_index);
if (tag == -)
{
n_signed = - n_signed;
m_signed = - m_signed;
isResetPosNeg = true;
}
else if (tag == )
{
result[] = '';
result[] = '\0';
return;
}
}
else if (n_signed == - && m_signed == )
{
int tag = AbsIsEqual(n, m, n_start, n_index, m_start, m_index);
if (tag == )
{
n_signed = - n_signed;
m_signed = - m_signed;
isResetPosNeg = true;
}
else if (tag == )
{
result[] = '';
result[] = '\0';
return;
}
} int index = ;
int nTake = ;
while (n_index >= n_start || m_index >= m_start)
{
int op1, op2;
op1 = op2 = ; if (n_index >= n_start && (n[n_index] < '' || n[n_index] > ''))
{
gInvalid = true;
return;
}
if (m_index >= m_start && (m[m_index] < '' || m[m_index] > ''))
{
gInvalid = true;
return;
} if (n_index >= n_start) op1 = n[n_index] - '';
if (m_index >= m_start) op2 = m[m_index] - '';
if (n_signed == && m_signed == -) op2 = m_signed * op2;
else if (m_signed == && n_signed == -) op1 = n_signed * op1; int nSum = op1 + op2 + nTake;
if (nSum >= )
{
nSum -= ;
result[index] = nSum + '';
nTake = ;
}
else if (nSum >= )
{
result[index] = nSum + '';
nTake = ;
}
else
{
nSum = + nSum;
result[index] = nSum + '';
nTake = -;
}
--n_index;
--m_index;
++index;
} if (nTake == ) result[index++] = nTake + '';
else if (nTake == -) result[index++] = '-'; if (isResetPosNeg) result[index++] = '-';
else if (n_signed == - && m_signed == -) result[index++] = '-'; result[index] = '\0';
} // 从后往前打印出这个数字,并忽略开头的0
void PrintNumber(char* number)
{
bool isBeginning0 = true;
int length = strlen(number); for (int i = length - ; i >= ; --i)
{
if (i == length - && number[i] == '-')
{
printf("%c", '-');
continue;
} if (isBeginning0 && number[i] != '')
{
isBeginning0 = false;
} if (!isBeginning0)
{
printf("%c", number[i]);
}
else
{
if (i == ) printf("%c", '');
}
}
} int main(void)
{
#ifdef Joshua_OJ
freopen("in.txt", "r", stdin);
#endif
int num;
char n[];
char m[];
char result[]; scanf("%d", &num);
while (num--)
{
scanf("%s %s", n, m);
BigNumberAdd(n, m, result);
if (gInvalid)
{
printf("%s\n", "invalid number");
continue;
}
PrintNumber(result);
printf("\n");
} #ifdef Joshua_OJ
fclose(stdin);
#endif return ;
}

输入第一个数表示有多少组数据,对于无效数据需要输出invalid number

Input:

15
200 -22
22 -200
-200 22
-22 200
0 0
000 000
-111 -111
-50 50
50 -50
-333 -333
222 -100
222.222 222
123222222222456 89701234562222222
11111111111111111 11111111111111100
9999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999

Output:

178
-178
-178
178
0
0
-222
0
0
-666
122
invalid number
89824456784444678
22222222222222211
19999999999999999999999999999999999999999999999999999998

C++实现两个大整数的相加(考虑到负数异常情况)的更多相关文章

  1. 华为OJ机试题目:两个大整数相乘(纯C语言实现两个大整数相乘,两种方法实现大数相乘)

    题目描述: 输出两个不超过100位的大整数的乘积. 输入: 输入两个大整数,如1234567 123 输出: 输出乘积,如:151851741 样例输入: 1234567 123 样例输出: 1518 ...

  2. C++ string 实现大整数相加减

    随意两个大整数的加减算法.可自己主动推断正负号.代码例如以下: #include <iostream> #include <vector> #include <cstri ...

  3. Javascript实现大整数加法

    记得之前面试还被问到过用两个字符串实现两个大整数相加,当时还特别好奇好好的整数相加,为什么要用字符串去执行.哈哈,感觉当时自己还是很无知的,面试官肯定特别的无奈.今天在刷算法的时候,无意中看到了为什么 ...

  4. ACM学习之路————一个大整数与一个小整数不得不说得的秘密

    这个相对于两个大整数的运算来说,只能说是,low爆了. 只要利用好除法的性质,这类题便迎刃而解.O(∩_∩)O哈哈~ //大整数除一个int数 #include<iostream> #in ...

  5. 大整数算法[11] Karatsuba乘法

    ★ 引子         前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...

  6. 大整数乘法python3实现

    因为python具有无限精度的int类型,所以用python实现大整数乘法是没意义的,可是思想是一样的.利用的规律是:第一个数的第i位和第二个数大第j位相乘,一定累加到结果的第i+j位上,这里是从0位 ...

  7. [转]大整数算法[11] Karatsuba乘法

    ★ 引子         前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...

  8. 算法笔记_034:大整数乘法(Java)

    目录 1 问题描述 2 解决方案 2.1 蛮力法   1 问题描述 计算两个大整数相乘的结果. 2 解决方案 2.1 蛮力法 package com.liuzhen.chapter5; import ...

  9. Coefficient Computation (大整数、Java解决)

    Coefficient Computation UVALive8265 题意:计算组合数C(n,k)的值并将值按给定的进制输出. 思路:Java大整数类硬上. PS:刚刚学完Java的大整数类,结果却 ...

随机推荐

  1. vim 多个文件切换 :b 命令

    MiniBufExplorer插件的使用 博客分类: vim vimMiniBufExplorer 快速浏览和操作Buffer -- 插件: MiniBufExplorer 下载地址 [http:// ...

  2. BugPhobia开发篇章:Scurm Meeting-更新至0x03

    0x01 :目录与摘要 If you weeped for the missing sunset, you would miss all the shining stars 索引 提纲 整理与更新记录 ...

  3. 20172319 2018.03.27-04.05 《Java程序设计》第4周学习总结

    20172319 2018.03.27-04.05 <Java程序设计>第4周学习总结 教材学习内容总结 第四章 编写类 类与对象的回顾:对象是有状态的,状态由对象的属性值确定.属性由类中 ...

  4. Journal entry of the thirteenth chapter to chapter seventeenth(第十三章和十七章阅读与疑问)

    第十三章: 软件测试的意义在于: a.     发现软件错误: b.     有效定义和实现软件成分由低层到高层的组装过程: c.     验证软件是否满足任务书和系统定义文档所规定的技术要求: d. ...

  5. golang数据类型转换

    int--string //string到int value_int,err:=strconv.Atoi(string) //int到string str:=strconv.Itoa(value_in ...

  6. 四则运算结对项目之GUI

    本次结对编程让我学到了许多许多知识,受益匪浅!在此之前,我没想过我能做出一个双击运行的小程序. 感谢我的队友与我同心协力,感谢室友宇欣告诉我操作符为“最多多少”而不是“多少”并教我使用效能分析工具,感 ...

  7. jquery on 事件嵌套 事件执行多次

    今天做了个项目,就是想点击添加然后追加一列,点击这一列的修改按钮,在修改, //编辑事件 $('#eventTable').on('click','.edit_n',function(){ var i ...

  8. 软工网络15团队作业8——Beta阶段敏捷冲刺(Day3)

    提供当天站立式会议照片一张 每个人的工作 1.讨论项目每个成员的昨天进展 赵铭: 还是在学习知晓云数据库怎么用 吴慧婷:这两天进一步进行界面设计,暂时完成了背单词界面的初步设计. 陈敏: 完成了背单词 ...

  9. PHP-时间函数

    1.时间格式化函数date(format,timestamp) format 时间格式 timestamp 时间戳 下面列出了一些常用于日期的字符: d - 表示月里的某天(01-31) m - 表示 ...

  10. 【百度】大型网站的HTTPS实践(一)——HTTPS协议和原理

    大型网站的HTTPS实践(一)——HTTPS协议和原理 原创 网络通信/物联网 作者:AIOps智能运维 时间:2018-11-09 15:07:39  349  0 前言 百度于2015年上线了全站 ...