实现两个大整数的相加,首先应该排除直接使用int和long long的方法,这些方法很容易溢出,这里为了方便(是否可以使用更精简的结构存储?)采用char来存储整数,整体思路如下:
1. 对于整数n和m的字符串形式,按照数组索引的从大到小累加计算,直接将结果存储到对应的result字符串中,处理完毕后再将result逆序输出,需考虑0和-的输出情况;
2. 考虑到有负号的情况,一开始就需要判断负号字符,这里将(-,-)和(+,+)统一当成相加操作然后都是负号的话在结尾补上负号,对于(+,-)和(-,+)统一处理成(大-小)的形式然后在结尾补负号;比如对于20-500转换成-(-20+500),对于-500+20准换成-(500-20)。
3. 这里需要使用标志位nTake记录是否进位或借位;
4. 还要考虑是否有异常字符出现,使用全局变量gInvalid记录有无异常。
1 #include<stdio.h> 2 #include<string.h> 3 4 #define Joshua_OJ 5 6 bool gInvalid = false; 7 8 // 0: equal, -1: n less m, 1: n bigger m 9 int AbsIsEqual(char* n, char* m, int n_start, int n_end, int m_start, int m_end) 10 { 11 if ((n_end - n_start) > (m_end - m_start)) return 1; 12 else if ((n_end - n_start) < (m_end - m_start)) return -1; 13 else 14 { 15 int i = n_start; 16 int j = m_start; 17 while (i <= n_end && j <= m_end) 18 { 19 if (n[i] > m[j]) return 1; 20 else if (n[i] < m[j]) return -1; 21 ++i; 22 ++j; 23 } 24 } 25 return 0; 26 } 27 28 void BigNumberAdd(char* n, char* m, char* result) 29 { 30 gInvalid = false; 31 32 if (n == NULL || m == NULL) 33 { 34 gInvalid = true; 35 return; 36 } 37 38 int n_index = strlen(n) - 1; 39 int m_index = strlen(m) - 1; 40 41 // 负数特别处理 42 int n_start = 0; 43 int m_start = 0; 44 int n_signed = 1; 45 int m_signed = 1; 46 if (n[0] == '-') 47 { 48 n_start = 1; 49 n_signed = -1; 50 } 51 if (m[0] == '-') 52 { 53 m_start = 1; 54 m_signed = -1; 55 } 56 // 如果只有一个负数,转换为大数减小数再取负号,这样方便异号借位相减 57 bool isResetPosNeg = false; 58 if (n_signed == 1 && m_signed == -1) 59 { 60 int tag = AbsIsEqual(n, m, n_start, n_index, m_start, m_index); 61 if (tag == -1) 62 { 63 n_signed = 0 - n_signed; 64 m_signed = 0 - m_signed; 65 isResetPosNeg = true; 66 } 67 else if (tag == 0) 68 { 69 result[0] = '0'; 70 result[1] = '