C/C++语言最新华为机试题“大数相加算法”
来源:互联网 发布:淘宝太空棉衣服真的吗 编辑:程序博客网 时间:2024/05/02 14:59
函数原型介绍:
// first和second:任意大小的十进制字符串整数,该函数主要解决超出int和long值域的大型整数加法运算// first和second的取值范围:可以是"99999999999999999"、"-9999999999999999999"和"0"等// result:存储相加的结果void add_large_integer(const char* first, const char* second, char* result);实现原理介绍:整数相加问题可以归结为两个子问题,即”正整数相加和正整数相减“,相加需要考虑进位的情况,相减则考虑借位的情况,按照测试驱动开发的原则,写上若干测试用例,如下所示:
#include <assert.h>#include <string>using namespace std;int main(int argc, char* argv[]){ char result[2048] = {0}; // 用例1 add_large_integer("99999999999999999999", "99999999999999999999", result); assert(0 == strcmp(result, "199999999999999999998")); // 用例2 result[0] = '\0'; add_large_integer("-99999999999999999999", "6666666666666666666666666666666", result); assert(0 == strcmp(result, "6666666666566666666666666666667")); return 0;}将要用到的辅助函数列表,原型如下:
// 跳过连续无效数字const char* skip_serial_number(const char* integer, int number);// 反转字符串char* reverse_string(char* p);// 判断是否正整数bool is_positive_integer(const char* integer);// 判断是否负整数bool is_negative_integer(const char* integer);// 正整数相加void add_positive_integer(const char* first, const char* second, char* result);// 正整数相减void minus_positive_integer(const char* large, const char* small, char* result);函数实现:
// 大数相加算法void add_large_integer(const char* first, const char* second, char* result){ // 数据有效性校验 if ( !(is_positive_integer(first) || is_negative_integer(first)) || !(is_positive_integer(second) || is_negative_integer(second)) ) { return; } // 两个正整数相加 if ( is_positive_integer(first) && is_positive_integer(second) ) { // 跳过无效字符 first = skip_serial_number(first, '0'); second = skip_serial_number(second, '0'); // 保存两个整数 string first_number(first ? first : ""); string second_number(second ? second : ""); // 字符串反转,使得个位对齐 first = reverse_string((char*)first_number.c_str()); second = reverse_string((char*)second_number.c_str()); add_positive_integer(first, second, result); // 两个正整数相加 reverse_string(result); // 反转result字符串结果 } // 两个负整数相加 else if ( is_negative_integer(first) && is_negative_integer(second) ) { strcpy(result, "-"); // 添加负号 add_large_integer(++first, ++second, ++result); // 跳过负号,变为正整数相加 } // 正整数和负整数相加 else { if ( is_negative_integer(first) ) // first为负数,second为正数 { ++first; // 移除负号; // 跳过无效符号 first = skip_serial_number(first, '0'); second = skip_serial_number(second, '0'); // 保存两个正整数 string first_number(first ? first : ""); string second_number(second ? second : ""); // 比较两个正整数的大小 int first_len = first ? strlen(first) : 0; int second_len = second ? strlen(second) : 0; int retcode = (first_len > second_len) ? 1 : \ ((first_len < second_len) ? -1 : strcmp(first, second)); if ( 0 == retcode ) { strcpy(result, "0"); // 相加和等于零 return; } else { // 字符串反转,使得个位对齐 first = reverse_string((char*)first_number.c_str()); second = reverse_string((char*)second_number.c_str()); if ( retcode < 0 ) // 负数的绝对值小于正数,相加后为正数 { minus_positive_integer(second, first, result); // 求绝对值的差 } else // 负数的绝对值大于正数,相加后为负数 { strcpy(result, "-"); // 添加负号 minus_positive_integer(first, second, ++result); // 求绝对值的差 } reverse_string(result); // 反转result字符串结果 } } else // first为正数,second为负数 { add_large_integer(second, first, result); // 递归调用 } }}
// 跳过连续无效数字const char* skip_serial_number(const char* integer, int number){ while ( integer && *integer && (*integer == number) ) { ++integer; } return integer;}
// 反转字符串char* reverse_string(char* p){ int length = strlen(p); for (int i = 0; i < (length / 2); ++i) { swap(p[i], p[length - i - 1]); } return p;}
// 判断是否正整数bool is_positive_integer(const char* integer){ while ( integer && *integer ) { if ( (*integer < '0') || (*integer > '9') ) { return false; } ++integer; } return true;}
// 判断是否负整数bool is_negative_integer(const char* integer){ // 负数符号 if ( integer && *integer && (*integer == '-') ) { return is_positive_integer(++integer); // 移除负号后判断是否正整数 } return false;}
// 正整数相加void add_positive_integer(const char* first, const char* second, char* result){ // 结束条件 if ( !first || !second || !result || (!*first && !*second) ) { return; } // 计算三者的和以及进位 int first_value = *first ? (*first - '0') : 0; int second_value = *second ? (*second - '0') : 0; int result_value = *result ? (*result - '0') : 0; int sum = first_value + second_value + result_value; // 计算当前位的值 *result = (sum % 10) + '0'; // 计算进位的值 if ( sum >= 10 ) { *(result + 1) = (sum / 10) + '0'; *(result + 2) = '\0'; // 添加结束符 } else { *(result + 1) = '\0'; // 添加结束符 } // 递归调用 first = *first ? ++first : first; second = *second ? ++second : second; add_positive_integer(first, second, ++result);}
// 正整数相减void minus_positive_integer(const char* large, const char* small, char* result){ // 结束条件 if ( !large || !small || !result || (!*large && !*small) ) { return; } // 计算当前位的差值 int borrow_value = *result ? 1 : 0; // 通过result保存借位情况 int large_value = *large ? ((*large - '0') - borrow_value) : 0; int small_value = *small ? (*small - '0') : 0; if ( large_value < small_value ) { *result = ((large_value + 10) - small_value) + '0'; // 借位相减 *(result + 1) = '-'; // 借出一位 *(result + 2) = '\0'; // 添加结束符 } else { *result = (large_value - small_value) + '0'; *(result + 1) = '\0'; // 添加结束符 } // 递归调用 small = *small ? ++small : small; minus_positive_integer(++large, small, ++result);}
- C/C++语言最新华为机试题“大数相加算法”
- C语言大数相加
- c语言 大数相加
- C语言大数相加
- C语言---大数相加
- C/C++“大数相加算法”
- 大数相加(C语言)
- 两个大数相加 C语言
- C语言之大数相加
- C语言 ☞ 大数相加
- 华为机试题--- 大数相加 异常处理
- 2014华为机试题2:大数相加
- c语言大数乘法各位相加问题
- C语言:大数相加与大数相减.
- C语言 大数相加与大数相减
- 大数相加(C实现
- 【c++】大数相加
- 大数相加 C/C++
- c#
- 如何使用Objective-C解析HTML和XML
- QuickContact分析及其弹出窗口实现
- 批处理——重命名特殊文件名
- 笔试
- C/C++语言最新华为机试题“大数相加算法”
- 1302. Magic Square (奇数幻方,找规律)
- "DAMAGE:after Normal block"的解决方法
- linux常用命令学习之head/tail命令
- 如何给模拟器发短信
- C/C++中的结构体对齐问题(内存对齐)
- 黑客自筑城堡 写出号称最安全的UNIX--(转载)
- JAVA 内省
- Algorithm of the Week: Merge Sort