实现两个大整数的相加,首先应该排除直接使用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. Kubernetes探索学习003--关于Kubernetes的Pod

    关于Pod 关于Pod我们要慢慢去体会去接受它去使用它,尤其是运维人员这块需要从逻辑上形成认识,首先理解Pod是Kubernetes项目的原子调度单位.为什么是Pod而不是单个DockerContai ...

  2. 前端_CSS

    目录 CSS语法 CSS的四种引入方式 CSS选择器 CSS属性操作 补充 示例(一些小模板) CSS语法 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. 1 2 3 4 5 6 7 ...

  3. Task 6.1 校友聊之NABCD模型分析

    我们团队开发的一款软件是“校友聊”--一个在局域网内免流量进行文字.语音.视频聊天的软件.下面将对此进行NABCD的模型分析. N(Need需求):现如今,随着网络的迅速普及,手机和电脑已经成为每个大 ...

  4. Class 1

    “在最艰苦的时候,就是你离成功最近的时候”,让暴风雨来得更猛烈些吧. 健身教练/学员,买的那本Java Web还是那么新,显然假期偷懒了,只能一点一点的补回来了.一个假期没有打开过自己的脑洞,真心醉了 ...

  5. Math 类的使用(一小部分)

    package com.Date.Math; /* Math 数学类, 主要是提供了很多的数学公式. abs(double a) 获取绝对值 ceil(double a) 向上取整 floor(dou ...

  6. 1001. A+B Format (20)的解题思路以及多源代码文件的尝试编写

    前言 这几天刚学了多源代码文件的编译,因为想尝试使用一下这种方法,所以想用此编写这次作业的程序.正好可以learning by doing,在做当中学习新知识.(编译器为Dev-C++) github ...

  7. AttributeError: module ‘tensorflow.python.ops.nn’ has no attribute ‘leaky_relu’

    #AttributeError: module 'tensorflow.python.ops.nn' has no attribute 'leaky_relu' 的原因主要是版本的问题 解决方法是更新 ...

  8. 【大数据应用技术】作业八|爬虫综合大作业Molly134

    本次作业的要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3075 前言:本次作业是爬取CBO中国票房2010-2019年每年 ...

  9. JavaBean 与 EJB 的区别

    JavaBean在一般情况下指的是实体类,在大部分情况下和POJO是同义词,基本构成就是一些字段和与之对应的 setter.getter方法,如果一个JavaBean需要在不同的JVM的进程中进行传递 ...

  10. paperOne基于java web的简易四则运算出题网站

    项目成员:张金生     张政 需求概要 1.运算数均为正整数 2.包含的运算符有+,-,*,/ 3.除法运算结果为整除运算 4.批量生成题目并判题 核心功能分析 1.题目生成——java后端 题目生 ...