您的位置:首页 > 职场人生

面试题13之大数的四则运算(续)

2013-08-17 14:21 288 查看
万恶的CSDN已经无力吐槽了,随便一搞,代码格式就乱成一团,这里把代码再调整一下。原文:http://blog.csdn.net/kay_zhyu/article/details/8877032

//两个字符串相加
//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;
}


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: