面试题13之大数的四则运算(续)
2013-08-17 14:21
288 查看
万恶的CSDN已经无力吐槽了,随便一搞,代码格式就乱成一团,这里把代码再调整一下。原文:http://blog.csdn.net/kay_zhyu/article/details/8877032
照旧,给出辅助函数和变量定义,以及main函数的调用,不需要者可以pass~~~~
//两个字符串相加 //str1和str2是加数,ans是结果数组,nMaxLen是结果数组的最大空间 char* Add(char* const str1, char* const str2, char *ans, int nMaxLen) { //一些参数检验 if(!str1 || !str2 || !ans || nMaxLen < 1) return NULL; //保证是两个整数相加 if(str1[0] == '-' && str2[0] == '-')//负加负 { ans[0] = '-'; if(Add(str1 + 1, str2 + 1, ans + 1, nMaxLen - 1)) return ans; else return NULL; } else if(str1[0] == '-')//一正一负 { return Minus(str2, str1 + 1, ans, nMaxLen); } else if(str2[0] == '-') { return Minus(str1, str2 + 1, ans, nMaxLen); } int nLen1 = strlen(str1); if(nMaxLen < nLen1) return NULL; int nLen2 = strlen(str2); if(nMaxLen < nLen2) return NULL; int i,j,k; int a,b,carry; carry = 0; //加公共部分 for(i = nLen1 - 1, j = nLen2 - 1, k = 0; (i >= 0 && j >= 0 && k < nMaxLen); --i,--j,++k) { a = str1[i] - '0'; b = str2[j] - '0'; ans[k] = (a + b + carry) % 10 + '0'; carry = (a + b + carry) / 10; } //加str1的多余部分 for( ; (i >= 0 && k < nMaxLen); --i, ++k) { a = str1[i] - '0'; ans[k] = (a + carry) % 10 + '0'; carry = (a + carry) / 10; } //加str2的多余部分 for( ; (j >= 0 && k < nMaxLen); --j, ++k) { b = str1[j] - '0'; ans[k] = (b + carry) % 10 + '0'; carry = (b + carry) / 10; } if(carry > 0 && k < nMaxLen) ans[k++] = carry + '0'; //结果的越界检查 if(k >= nMaxLen) return NULL; //加上结束标记 ans[k] = '\0'; Invert(ans, k); return ans; } //两个大数相减 //str1-str2,ans表示结果,nMaxLen表示ans的最大长度 char* Minus(char* const str1, char * const str2, char *ans, int nMaxLen) { //一些参数检验 if(!str1 || !str2 || !ans || nMaxLen < 1) return NULL; //保证是正数减正数 if(str1[0] != '-' && str2[0] == '-')//正减负 return Add(str1, str2 + 1, ans, nMaxLen); else if(str1[0] == '-' && str2[0] == '-')//负减负 return Minus(str2 + 1, str1 + 1, ans, nMaxLen); else if(str1[0] == '-' && str2[0] != '-')//负减正 { ans[0] = '-'; if(Add(str1 + 1, str2, ans + 1, nMaxLen - 1)) return ans; else return NULL; } //保证str1大于str2 int nLen1 = strlen(str1); if(nMaxLen < nLen1) return NULL; int nLen2 = strlen(str2); if(nMaxLen < nLen2) return NULL; //其实这里直接是str1[0]<str2[0]是有bug的,应该是strcmp(str1,str2),确认str1<str2 if(nLen1 < nLen2 || (nLen1 == nLen2 && str1[0] < str2[0])) { ans[0] = '-'; if(Minus(str2, str1, ans + 1, nMaxLen - 1)) return ans; else return NULL; } int i,j,k; int a,b,carry; bool IsPos = true; carry = 0; //减去公共的部分,str1大于str2 for(i = nLen1 - 1, j = nLen2 - 1, k = 0;(i>= 0 && j >= 0 && k < nMaxLen); --i,--j,++k) {a = str1[i] - '0' - carry;b = str2[j] - '0'; if(a < b) {a += 10;carry = 1;} else carry = 0; ans[k] = a - b + '0'; } //得到str1剩余的部分 for(; (i >= 0 && k < nMaxLen); --i,++k) { a = str1[i] - '0' - carry; if(a < carry) { a += 10; carry= 1; } else carry = 0; ans[k] = a + '0'; } if(carry > 0 && k < nMaxLen) ans[k++] = '-'; if(k >= nMaxLen) return NULL; ans[k] = '\0'; Invert(ans, k); return ans; } //大数乘法//str1*str2,ans是结果,nMaxLen是ans的最大容量 char *Mutiply(char* const str1, char* const str2, char *ans, int nMaxLen) { if(!str1 || !str2 || !ans || nMaxLen < 1)return NULL; //保证是两个正数相乘 if(str1[0] == '-' && str2[0] == '-') return Mutiply(str1 + 1, str2 + 1, ans, nMaxLen); else if(str1[0] == '-') { ans[0] = '-'; if(Mutiply(str1 + 1, str2, ans + 1, nMaxLen)) return ans; else return NULL; } else if(str2[0] == '-') { ans[0] = '-'; if(Mutiply(str1, str2 + 1, ans + 1, nMaxLen)) return ans; else return NULL; } int nLen1 = strlen(str1); int nLen2 = strlen(str2); if(nMaxLen < nLen1 + nLen2 - 1) //内存不够,返回 return NULL; int *arr = (int *)malloc((nLen1 + nLen2 + 1)*sizeof(int)); if(!arr) //内存申请失败,返回 return NULL; memset(arr, 0, (nLen1 + nLen2 + 1)*sizeof(int)); int i,j; for(i = 0; i < nLen1; ++i) { for(j = 0; j < nLen2; ++j){arr[i+j] += (str1[i] - '0') * (str2[j] - '0'); } } int k,carry;carry = 0; //乘积的结果转移到ans中 for(k = 0, i = nLen1 + nLen2 - 2; i >= 0 && k < nMaxLen;--i,++k) { ans[k] = (arr[i] + carry) % 10 + '0';carry = (arr[i] + carry) / 10; } free(arr); //释放辅助内存 arr = NULL; while(carry > 0 && k < nMaxLen) { ans[k++] = carry % 10 + '0'; carry /= 10; } //检查是否溢出 if(k > nMaxLen) return NULL; ans[k] = '\0'; Invert(ans, k); return ans; }
照旧,给出辅助函数和变量定义,以及main函数的调用,不需要者可以pass~~~~
#include<string.h> #include<malloc.h> char* Add(char* const str1, char* const str2, char *ans, int nMaxLen); char* Minus(char* const str1, char * const str2, char *ans, int nMaxLen); //反转字符串 void Invert(char *str, int nLen) { if(!str || nLen < 1) return; char temp; for(int i = 0; i < nLen>>1; ++i) { temp = str[i]; str[i] = str[nLen - 1 - i]; str[nLen - 1 - i] = temp; } } int main() { const int N = 50; char str1 ; char str2 ; char ans ; char *p; while(scanf("%s %s", str1, str2) != EOF) { p = Add(str1, str2, ans, N);//加 if(p) puts(p); p = Minus(str1, str2, ans, N);//减 if(p) puts(p); p = Mutiply(str1, str2, ans, N);//乘 if(p) puts(p); } return 0; }
相关文章推荐
- 面试100题系列之13大数的四则运算
- 面试100题系列之13大数的四则运算
- 算法-大数的四则运算
- 面试题 简单的字符串表达式四则运算(不考虑括号)
- 【C++】大数的+-*/四则运算
- 高精度(大数)的四则运算与逻辑运算---c++ struct版
- 利用位运算实现四则运算 -- 华为面试题
- c语言面试题之大数运算
- 大数的四则运算之乘法----Java代码实现
- 大数的四则运算(转)
- c语言面试题之大数运算
- 华为面试题:四则运算 C语言源码
- 面试题45:字符串四则运算的实现
- 面试题(十五)四则运算表达式
- 大数的四则运算之除法----Java代码实现
- 大数的四则运算
- 面试题之总结-大数运算
- 面试题45:字符串四则运算的实现
- 大数的四则运算及求模
- 大数项目:用字符串表示超过内存表示范围的大数据并实现四则运算