本来是打算写四种大整数的计算的,但是除法没有成功,因为当初只看到了题目里面求加法的计算,突发奇想准备把四种都写处出来,但是一开始的时候没有考虑到除法会用到减法,函数运行一直出错,以后思考了,先放过去了。
题目当时要求计算长的整数的加法,数据为比较多的,其实无非就是不能直接用一个变量存储的整数的运算。
感悟:大数据的处理,感觉就是考察对数组的运用,加法和减法的处理是比较简单的,但是乘法和除法的处理就需要很强的技巧了。除法的自己还没有想好
#include<stdio.h>
#include<string.h>
/**计算数字长度少于200内的乘法*/
#define M 200
/**这些都是一些全局数组,当时只是写了加法,其他的都是后来一时有兴趣写的,所以没有把数组放到函数里面。
而且数组这么大,放进去不太好*/
char op_1[M+1]={0};
char op_2[M+1]={0};
char result[2*(M+1)]={0};//积的位数最多为乘数中位数较大的二倍
char result_div[2*(M+1)]={'0'};
char div_tem[M+1]="1";
/**对两个数加减的时候,位数不想等的时候要保证又对齐,不论什么情况都是从右向左操作的,为了防止数组向左
越界,必须处理,可以每次都在程序判断哪一个存储数据的数组下标到0了,到0后就加0,也可以上来就把两个补齐
变成一样长的,以后不用处理了。*/
int init(char*add_1,char *add_2)
{
int i=0,off;
if(strlen(add_1)>strlen(add_2))
{
off=strlen(add_1)-strlen(add_2);
for(i=strlen(add_2)-1;i>=0;i--)
{
add_2[i+off]=add_2[i];
}
for(i=0;i<off;i++)
{
add_2[i]='0';
}
}
if(strlen(add_2)>strlen(add_1))
{
off=strlen(add_2)-strlen(add_1);
for(i=strlen(add_1)-1;i>=0;i--)
{
add_1[i+off]=add_1[i];
}
for(i=0;i<off;i++)
{
add_1[i]='0';
}
}
return strlen(add_2);
}
/**加法很好求,就是小学生竖式运算,按步骤来就行*/
void calculate_add(char*add_1,char *add_2)
{
int r=0,i,j,len;
len=init(add_1,add_2)-1;
for(i=len,j=0,r=0;i>=0;i--,j++)
{
result[j]=(add_1[i]-'0'+add_2[i]-'0'+r)%10+'0';
r=(add_1[i]-'0'+add_2[i]-'0'+r)/10;
}
if(r!=0)
result[j]=r+'0';
}
/**减法很加法没有什么区别,无法就是一个负数,先根据补齐后的数组第一位的大小就可以判断大小,然后运算
最后决定加不加负号就可以了*/
void calculate_sub(char*Sub_1,char *Sub_2)
{
int i,j,len,r=0,flag=0;
char *sub_1,*sub_2;
len=init(Sub_1,Sub_2)-1;
if(Sub_1[0]<Sub_2[0])/***第一处*/
{
sub_2=Sub_1;
sub_1=Sub_2;
flag=1;
}
else
{
sub_1=Sub_1;
sub_2=Sub_2;
}
for(i=len,j=0,r=0;i>=0;i--,j++)
{
if(sub_1[i]>=sub_2[i])
{
result[j]=sub_1[i]-sub_2[i]+'0';
}
else
{
if(sub_1[i]==('0'-1))//被借位前是0的情况
{
result[j]='9'-sub_2[i]+'0';
}
else
{
result[j]=10+sub_1[i]-sub_2[i]+'0';
}
sub_1[i-1]=sub_1[i-1]-1;/**第一处保证这里不会越界小于0*/
}
}
if(result[j-1]=='0')//这里不同与加法的判断,加法可能出现比加数多一位的情况,所以是对result[j]做判断
result[j-1]='\0';//减法不会,所以对j-1进行操作,要的是消除多余的0
if(flag==1)//负号是附加信息,应该在前面所有操作完成后进行决定添加与否
result[strlen(result)]='-';
}
/**乘法本来想安装现实那样计算,但是如果真的按照现实计算需要一个很大的二维数组,浪费空间严重不说,
而且要最后对数组的每一行进行错位累加,感觉很麻烦。时间空间都比较浪费。所以自己分析了下过程,每次计算都
进行错位累加,即节省了时间也节省了空间*/
void calculate_mul(char *mul_1,char *mul_2)
{
int i,j,k=0,off=-1,r=0;
int temp0;
for(i=strlen(mul_2)-1;i>=0;i--)
{
r=0;//进位的数值设置为0
off++;//偏移量每次都要加1,模拟手动计算的时候的每次错一位
k=0;
for(j=strlen(mul_1)-1;j>=0;j--)
{
if(result[k+off]==0)//数组原来的值没有变
{
result[k+off]=((mul_1[j]-'0')*(mul_2[i]-'0')+r)%10+'0';//计算
r=((mul_1[j]-'0')*(mul_2[i]-'0')+r)/10;
}
else//进行错位加法计算
{
temp0=result[k+off]-'0';
result[k+off]=(result[k+off]-'0'+(mul_1[j]-'0')*(mul_2[i]-'0')+r)%10+'0';
r=(temp0+(mul_1[j]-'0')*(mul_2[i]-'0')+r)/10;
}
k++;
}
if(r!=0)
{
result[k+off]='0'+r;
}
}
}
/**除法就没有那么好运了,想不出类似乘法的办法,本来想用现实那样进行试除,感觉那样运算不好。
下面是打算进行用第一个数减去第二个数,计算减到负数的次数。就是结果,但是没有成功啊!!感觉这样
其实效率也很低,每次都进行加1,数据特别大的时候时间肯定超时了,这种方法其实也不好*/
int calculate_div(char *div_1,char *div_2)
{
int i,k=0;
memset(result,0,sizeof(result));
calculate_sub(div_1,div_2);
if(result[strlen(result)-1]=='-')//第一个数比第二个数小的时候
{
result[0]='0';
result[1]='\0';
return 1;
}
for(i=strlen(result)-1;i>=0;i--)//帮刚刚做的减法操作的result里的结果保存到div_1
{
div_1[k++]=result[i];
}
div_1[k]='\0';//不能忘记了结束标志
memset(result,0,sizeof(result));
calculate_add(result_div,div_tem);//因为上面不为0,所以要进行一次加一。
k=0;
for(i=strlen(result)-1;i>=0;i--)//帮刚刚做的减法操作的result里的结果保存到result_div
{
result_div[k++]=result[i];
}
result_div[k]='\0';
while(result[strlen(result)-1]!='-')
{
k=0;
memset(result,0,sizeof(result));//使用前要清零
calculate_sub(div_1,div_2);
for(i=strlen(result)-1;i>=0;i--)
{
div_1[k++]=result[i];
}
div_1[k]='\0';//不能忘记了结束标志
memset(result,0,sizeof(result));
calculate_add(result_div,div_tem);
k=0;
for(i=strlen(result)-1;i>=0;i--)
{
result_div[k++]=result[i];
}
result_div[k]='\0';
}
}
int main()
{
int i;
printf("请输入第一个数:\n");
gets(op_1);
printf("请输入第二个数:\n");
gets(op_2);
/**四种运算选择一个,做测试还是成功的*/
//calculate_add(op_1,op_2);
// calculate_sub(op_1,op_2);
calculate_mul(op_1,op_2);
for(i=strlen(result)-1;i>=0;i--)
{
putchar(result[i]);
}
return 0;
}<span style="font-weight: bold;">
</span>
乘法的截图