【算法】大整数加法
2012-07-29 19:42
183 查看
1.算法描述
为了表示大整数,一般采用字符数组,这样可以表示更多位的整数。在实现大整数加法时,可模拟小学生列竖式。首先,位对齐,两个大整数的个位对个位、十位对十位、百位对百位……然后,按位相加,如果满十,则置进位为1。两个大数的高位相加时,要加上进位。长度为n的字符数组在表示大整数时,[0]表示大整数的最高位,[n-1]表示大整数的最低位(即个位)。所以,在位对齐时,处理比较麻烦。
2.问题
2.1 九度OJ 1198
题目要求:实现一个加法器,使其能够输出a+b的值。源代码:
1198 | Accepted | 908KB | 2595B | 120MS | C / 代码 |
#include <stdio.h> #include <string.h> int main() { char a[1000],b[1000],c[1000],carry[1001]; //carry[i]表示进位 int i,j,k,temp,a_length,b_length; while(~scanf("%s%s",&a,&b)) { a_length=strlen(a); b_length=strlen(b); if(a_length<b_length) //a的位数比b的位数少 { memset(carry,'0',b_length+1); for(i=a_length-1,j=b_length-1,k=0;i>=0;i--,j--,k++) { temp=a[i]+b[j]+carry[k]-96; if(temp>57) { temp=temp-10; carry[k+1]='1'; } else carry[k+1]='0'; c[k]=(char) temp; } for(j=b_length-a_length-1,k=a_length;j>=0;j--,k++) { temp=b[j]+carry[k]-48; if(temp>57) { temp=temp-10; carry[k+1]='1'; } else carry[k+1]='0'; c[k]=(char) temp; } if(carry[b_length]=='1') //判断最高位是否有进位 { c[b_length]='1'; c[b_length+1]='\0'; } else c[b_length]='\0'; } else if(a_length==b_length) { memset(carry,'0',a_length+1); for(i=a_length-1,k=0;i>=-0;i--,k++) { temp=a[i]+b[i]+carry[k]-96; if(temp>57) { temp=temp-10; carry[k+1]='1'; } else carry[k+1]='0'; c[k]=(char) temp; } if(carry[a_length]=='1') { c[a_length]='1'; c[a_length+1]='\0'; } else c[a_length]='\0'; } else { memset(carry,'0',b_length+1); for(i=a_length-1,j=b_length-1,k=0;j>=0;i--,j--,k++) { temp=a[i]+b[j]+carry[k]-96; if(temp>57) { temp=temp-10; carry[k+1]='1'; } else carry[k+1]='0'; c[k]=(char) temp; } for(i=a_length-b_length-1,k=b_length;i>=0;i--,k++) { temp=a[i]+carry[k]-48; if(temp>57) { temp=temp-10; carry[k+1]='1'; } else carry[k+1]='0'; c[k]=(char) temp; } if(carry[a_length]=='1') { c[a_length]='1'; c[a_length+1]='\0'; } else c[a_length]='\0'; } int c_length=strlen(c); for(i=c_length-1;i>=0;i--) printf("%c",c[i]); printf("\n"); } return 0; }
2.2 POJ 1503
求:输入n个大数之和。用int数组sum存放运算结果,通过sum[ i ]>10判断是否有进位。
WA了几次,看Discuss,原来数组要开到105。
源代码:
1503 | Accepted | 116K | 0MS | C | 780B | 2013-08-26 10:45:55 |
#include "stdio.h" #include "string.h" #define MAX 105 int main() { int sum[MAX]; int i, j, leading_zero, ch_length; char ch[MAX]; memset(sum,0,sizeof(sum)); while(scanf("%s",&ch)) { ch_length=strlen(ch); if(ch_length==1&&ch[0]=='0') //judge the end of input break; for(i=MAX-1,j=ch_length-1; j>=0; i--,j--) sum[i]+=ch[j]-'0'; for(i=MAX-1,j=ch_length-1; j>=0; i--,j--) //deal with the carry { if(sum[i]>=10) { sum[i]%=10; sum[i-1]++; } } } /*deal with leading zero, output the sum*/ for(i=0,leading_zero=0; i<MAX; i++) if(sum[i]!=0) { leading_zero=i; break; } for(i=leading_zero;i<MAX;i++) printf("%d",sum[i]); printf("\n"); return 0; }
2.3 POJ 2413
求:区间[a, b]上的fibonacci数有几个。思路:用大整数加法求出前490个fibonacci数(其实,第480个fibonacci数就有100位了);用二分查找,找出a,b在fibonacci数组的位置,即可求出fibonacci数的个数。
用指针变量做形参才能改变变量的值,比如BinarySerach(, , ,*flag)而不是BinarySerach(, , ,flag)。二分查找没写好,WA了几次。代码参考十三年草 ,做了一些优化。
源代码:
2413 | Accepted | 168K | 0MS | C | 2337B | 2013-08-27 20:31:16 |
#include "stdio.h" #include "string.h" #define MAX 105 #define MAXnum 490 /*store fibonacci numbers*/ char fibonacci[MAXnum][MAX]; /*big inter addition*/ void Add(char *a, char *b, char *sum) { int i,j,k,leading_zero; int temp[MAX]; memset(temp,0,sizeof(temp)); for(i=strlen(a)-1,j=MAX-1;i>=0;i--,j--) temp[j]=a[i]-'0'; for(i=strlen(b)-1,k=MAX-1;i>=0;i--,k--) temp[k]+=b[i]-'0'; /*标记前导0的结束位置*/ leading_zero=j<k?j:k; /*deal with carry*/ for(i=MAX-1;i>=leading_zero;i--) { if(temp[i]>=10) { temp[i]%=10; temp[i-1]++; } } /*deal with leading zero*/ if(temp[leading_zero]==0) leading_zero++; for(i=0,j=leading_zero;j<=MAX-1;i++,j++) sum[i]=temp[j]+'0'; } /*compute fibonacci numbers*/ void ComputeFibo() { int i; memset(fibonacci,'\0',sizeof(fibonacci)); strcpy(fibonacci[1],"1"); strcpy(fibonacci[2],"2"); for(i=3;i<MAXnum;i++) Add(fibonacci[i-1],fibonacci[i-2],fibonacci[i]); } /*compare two strings*/ int Compare(char *a, char *b) { int a_length, b_length; a_length=strlen(a); b_length=strlen(b); if(a_length==b_length) return strcmp(a,b); else return a_length>b_length?1:-1; } /*当a不是fibonacci数时,二分查找返回的是第一个比a大的fibonacci数 flag标记查找元素a是否属于fibonacci数组*/ int BinarySearch(int low, int high, char *a, int *flag) { int pivot, comp; while(low<=high) { pivot=(low+high)/2; comp=Compare(a,fibonacci[pivot]); if(comp==0) { *flag=1; return pivot; } else if(comp<0) high=pivot-1; else low=pivot+1; } return low; } int main() { char a[MAX], b[MAX]; int a_length, b_length, a_start, b_start; int left_flag, right_flag; ComputeFibo(); while(scanf("%s%s",&a,&b)) { left_flag=0; right_flag=0; a_length=strlen(a); b_length=strlen(b); if(strcmp(a,"0")==0&&strcmp(b,"0")==0) break; a_start=BinarySearch(1,MAXnum-1,a,&left_flag); b_start=BinarySearch(a_start,MAXnum-1,b,&right_flag); if(right_flag) printf("%d\n",b_start-a_start+1); else printf("%d\n",b_start-a_start); } return 0; }
相关文章推荐
- 大整数算法[08] 有符号加法和减法
- 同位大整数加法算法
- 大整数算法[06] 绝对值加法
- 贪心算法-大整数乘法/加法/减法
- 【算法导论】2-1-4二进制整数加法.cpp
- 算法(求对输入的N个数进行加法或减法运算,得到最小的正整数的组合.)
- 如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算
- A+B长整数的加法(算法实现)
- 算法-大整数加法
- 【算法】大整数加法
- A+B长整数的加法(算法实现)
- A+B长整数的加法(算法实现)
- acm题目--正整数n的加法组合的最大乘积的超快算法
- 算法总结——大整数加法
- 大整数加法计算思路与算法实现
- 如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算)
- 【Java】给定一个有序整数数组,元素各不相同且按照升序排列,编写一个算法,创建一个高度最小的二叉查找树
- 整数算法训练02—有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的那位
- Hdu 1002 A + B Problem II(大整数加法)
- c++300位大整数加法