这几天无聊,突然想起来,大学当时有个问题困扰着我
两个超大的数怎么保存和相加呢,计算机的整形32位的最大也就4294967296,超过这个数就计算不了了哇
然后就想动手实践一下
思路:
1.超长数据怎么存呢。脑子一拍,巨长的数肯定用字符数组来存哇,没毛病。
2.要怎么运算呢。我想的是,一个数最大是4294967296,长度为10,那我两个9长度的数据相加,肯定不会超过1999999998,那我就把巨长的字符数组每九个切割成整形数组保存起来呗,这样就可以相加了。比如111111111222222222+3333333333444444444转化为111111111+3333333333和222222222+444444444然后把两个结果凑一起就成啦
3.嗯,这样的思路看起来没毛病,挺简单的。(MDZZ,对自己竖中指,真蠢的办法,代码写一半想到了更简单的方法,结尾说说)。那就动手吧。
代码:
ps:代码有点长,没办法,太傻了,写起来才发现,这种方法要考虑好多种情况,比如连续进位,两个数据不等长等等
#include<stdio.h>
//将字符数据转换成int类型数据,9个长度的为一个数据,调用atoi函数变为整形
//例如123456789087654321->第一个数据为087654321第二个数据为123456789
//倒着读入并转换成整形的
int convert(char *data,int *temp)
{
int lenth=strlen(data);//获取输入数据长度
int i=0,j=0,k=0;//i控制循环,从数据最后一个数据往前循环
//j控制分割字符保存入temp_data
//k用来返回数据转换了多少个9长度的整形数据
char temp_data[9];//中间变量,存分割出来的9个字符
for(i=lenth-1;i>=0;i--)
{
temp_data[8-j] = data[i];
j++;
if(j==9)
{
j=0;
temp[k]=atoi(temp_data);//转换成整形数据存入temp
k++;
memset(temp_data,0,sizeof(temp_data));
}
}
if(lenth%9 == 0)
return k-1;
while(j<9)//如果最后一个数据长度小于9,就填充0
{
temp_data[8-j] = '0';
j++;
}
temp[k]=atoi(temp_data);//最后一个数据
return k;
}
//计算函数,传参,
//第一个数据的整形数组
//数组使用长度
//第一个数据的整形数组
//数组使用长度
//结果保存整形数组
int calc(int *data1,int dw1,int *data2,int dw2,int *result)
{
int i=0,j=0,k=0,diff=0,diff_result=0,jw=0;//i,j控制循环读入数据1和数据2的数据
//k控制result数组长度
//diff为数据1与1000000000的差值,diff_result是数据2与diff的差值
//jw标志是否进位
for(i=0,j=0;i<=dw1&&j<=dw2;i++,j++)
{
result[k]=data1[i];
diff = 1000000000 - data1[i];
diff_result = data2[j] - diff;
if (diff_result > 0)//代表需要进位
{
result[k]=diff_result+jw;
jw=1;
}
else//无需进位
{
result[k]+=data2[j]+jw;
jw=0;
}
k++;
}
while(i<=dw1)//数据1长度比数据2长时接下来的数据处理
{
if(jw==1) //之前的数据是否有进位
{
if(data1[i]+1 >= 1000000000)//如果进位超过了1000000000,例如9999999999+111111111111
{
result[k]=0;
k++;
i++;
jw=1;
continue;
}
result[k]=data1[i]+1;
jw=0;
}
else
result[k]=data1[i];
k++;
i++;
}
while(j<=dw2)//数据2长度比数据1长时接下来的数据处理
{
if(jw==1)//之前的数据是否有进位
{
if(data2[j]+1 >= 1000000000)//如果进位超过了1000000000,例如9999999999+111111111111
{
result[k]=0;
k++;
j++;
jw=1;
continue;
}
result[k]=data2[j]+1;
jw=0;
}
else
result[k]=data2[j];
k++;
j++;
}
if(jw==1)
{
result[k]=1;
k++;
}
return k-1;//返回结果的整形数组存入数据的个数
}
int main()
{
char data1[100]={0,};//存第一个输入的数据,最长数据99位哟
char data2[100]={0,};//存第二个输入的数据,最长数据99位哟
int temp1[11]={0};//存第一个数据转化为整形的数据
int temp2[11]={0};//存第二个数据转化为整形的数据
int result[11]={0};//存结果的整形数据
int dw1=0,dw2=0,result_dw=0;//数组下标,对应数据1,2和结果
int i=0;//控制结果打印的循环
printf("input data1:");
gets(data1);
dw1=convert(data1,temp1);//数据1转化为整形数组
printf("input data2:");
gets(data2);
dw2=convert(data2,temp2);//数据2转化为整形数组
result_dw=calc(temp1,dw1,temp2,dw2,result);//计算
printf("#####result:");
for(i=result_dw;i>=0;i--)
{
if(i==result_dw)
printf("%d",result[i]);//开头数据不用0补齐
else
printf("%09d",result[i]);
}
printf("\n");
return 0;
}
这段代码写了我一个半小时,
半小时以为自己写完了
运行,有bug,不等长数据计算错误,转换有问题,显示有问题......
半小时以后以为自己写完了
运行,有bug,进位有问题,连续进位有问题......
半小时以后以为自己写完了
嗯,应该是写完了,没测出啥错误了,哭
原谅一个计算机萌新。。。不。。我都工作五个月了,写这种代码用了快两个小时,我对自己是个程序员表示羞愧,想去屎。
写到一半,写calc计算函数时候,我脑子里一闪,我为什么不直接让两个数据一个字符一个字符的相加,直接data1[n]+data2[n]-'0'-'0'不就行了嘛,在搞个标志看是否进位。。。。。。比我之前的想法简单多了,别拉我,让我去屎,不论从哪个方面看,算法,复杂度(这玩意我也不是很了解哈哈),看着我写的代码都像个傻子QAQ。
如果我想实践我后来的想法再写吧。完