以前刚进华为时,有一个考题,需要完成一个超大数相加,刚毕业那会儿比较嫩,没做出来,今天想了一下,还是能做出来的。
下面只是按照个人的思路,完成了超大数相加,但代码显然不够简洁,我以后会将其进一步完善。
思路:
如图:
这样就两个超大数计算完成。
需要注意的是:
1.因为是超大数,肯定不能用数据类型,只能用字符串存取
2.既然是字符串,就需要对每个字符进行转化成数字。
代码如下:
/*
完成了两个超大数相加
作者:wantin
时间:2016.6.20
*/
#include <stdio.h>
#include <string.h>
int CheckString(char *p);
int CheckSign(char a);
void add(char *p1,char *p2);
void main()
{
char str1[100] = {0};
char str2[100] = {0};
char Sign = 0;
char res=0;
while(1)
{
/* 获得第一个数 */
printf("第一个数:");
gets(str1);
res = CheckString(str1);
if(1 == res)
{
continue; // 当输入有误时,继续下一次重新输入
}
/* 获得运算符号 */
printf("运算符:");
Sign = getchar();
res = CheckSign(Sign);
if(1 == res)
{
continue;
}
/* 获得第二个数 */
printf("第二个数:");
gets(str2);
res = CheckString(str2);
if(1 == res)
{
continue; // 当输入有误时,继续下一次重新输入
}
if(0 == res)
{
break;
}
}
if('+'==Sign)
{
add(str1,str2);
}
}
/* 字符串合法性检测 */
int CheckString(char *p)
{
int len = 0;
int i = 0;
len = strlen(p);
if( 0==len )
{
gets(p);
}
for(i=0; i<len; i++)
{
if(p[i]<'0' || p[i]>'9')
{
puts("输入有误,请重新输入!!");
return 1;
}
}
return 0;
}
/* 运算符合法性检测 */
int CheckSign(char a)
{
if('+'==a)
{
return 0;
}
else
{
puts("运算符输入有误!!!");
return 1;
}
}
/* 加法运算 */
void add(char *p1,char *p2)
{
int len1 = 0;
int len2 = 0;
int i = 0;
int j = 0;
int k = 0;
int a = 0;
int b = 0;
int t=0;
char *pTemp;
int flag = 0;
int temp = 0;
char str[100]={0};
len1 = strlen(p1);
len2 = strlen(p2);
if(len2>len1)
{
t = len2;
len2 = len1;
len1 = t;
pTemp = p2;
p2 = p1;
p1 = pTemp;
}
k = len1;
for(i=len1-1,j=len2-1; j>=0; j--,i--,k--)
{
a = p1[i]-'0';
b = p2[j]-'0';
temp = a+b+flag;
if(temp<=9)
{
flag = 0;
str[k] = temp+'0';
}
else
{
str[k] = temp%10+'0'; // 取值转成字符存入数组
flag = 1; // 进位标记位
}
}
/*大数与小数相加,直到小数长度结束后,还需要判断大数剩下的是否需要进位操作*/
for(;i>=0;i--)
{
if(0 == flag)
{
str[k]=p1[i];
}
else
{
if(p1[i]=='9')
{
str[k] = '0';
flag=1;
}
else
{
str[k]=p1[i]+1;
flag = 0;
}
}
k--;
}
/* 确定最高位是否有进位,若有则需要对最高位的上一位进1操作 */
if(1==flag)
{
str[0]='1';
puts(str);
}
else
{
puts(&str[1]);
}
}
大家可以看一下,有问题共同讨论。