编程学习笔记3--大整数的运算
来源:互联网 发布:js实现动态时钟 编辑:程序博客网 时间:2024/06/10 18:42
本来是打算写四种大整数的计算的,但是除法没有成功,因为当初只看到了题目里面求加法的计算,突发奇想准备把四种都写处出来,但是一开始的时候没有考虑到除法会用到减法,函数运行一直出错,以后思考了,先放过去了。
题目当时要求计算长的整数的加法,数据为比较多的,其实无非就是不能直接用一个变量存储的整数的运算。
感悟:大数据的处理,感觉就是考察对数组的运用,加法和减法的处理是比较简单的,但是乘法和除法的处理就需要很强的技巧了。除法的自己还没有想好
#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>
乘法的截图
0 0
- 编程学习笔记3--大整数的运算
- 大整数的运算实现
- 大整数的乘法运算
- 大整数的乘法运算
- 大整数的加法运算
- 大整数的乘法运算
- 大整数的加减乘除运算
- 模拟手算的大整数乘法学习笔记
- java是实现的大整数运算!
- 一个大整数运算的类
- 大整数的乘法与阶乘运算
- 大整数的加减乘运算
- 大整数的加法和乘法运算
- 大整数的加乘多项式运算
- 基于C++的大整数运算操作
- 大整数的4则运算
- Problem B: 大整数的加法运算
- Problem I: 大整数的加法运算
- CSU 1407: 最短距离(数学啊 )
- 【HDU 1158】 Employment Plannin
- 灰度世界算法(Gray World Algorithm)
- 《HotSpot实战》笔记2类与对象
- C语言基础之数组、字符串、指针
- 编程学习笔记3--大整数的运算
- android中string.xml中%1$s、%1$d等的用法
- CSU 1408: 种植树苗(贪心啊 )
- HDU2734:Quicksum
- android 下 对3G 模块进行AT 命令调试
- 谈下自己,我比较精通J2SE,熟悉J2SE里的Servlet等
- 20个最热门的IT技术职位及薪资
- 设计模式-组合模式
- HDU 2393 Higher Math