求两个不超过100位的非负整数的和,差,乘,除
2013-12-01 19:30
232 查看
思想:
用字符串来控制输入,数组来存储,数组的低位存整数的低位,高位来存储高位,
和:计算的过程基本上和小学生列竖式做加法相同。
差:跟和差不多
乘:计算的过程基本上和列竖式做乘法相同。为编程方便,并不急于处理进位,而将进位问题留待最后统一处理
除:基本的思想是反复做减法,看看从被除数里最多能减去多少个除数,商就是多少。一个一个减显然太慢,如何减得更快一些呢?以7546除以23 为例来看一下:开始商为0。先减去23 的100 倍,就是2300,发现够减3
次,余下646。于是商的值就增加300。然后用646 减去230,发现够减2次,余下186,于是商的值增加20。最后用186 减去23,够减8 次,因此最终商就是328。
n的核心是要写一个大整数的减法函数,然后反复调用该函数进行减法操作。 计算除数的10倍、100 倍的时候,不用做乘法,直接在除数后面补0 即可。
测试:
666666666666666666666666666666666666666666666666666666666666666666
22222222222222222222222222222222222222222222222222222222222222222
和:688888888888888888888888888888888888888888888888888888888888888888
差:644444444444444444444444444444444444444444444444444444444444444444
乘:14814814814814814814814814814814814814814814814814814814814814814651851851851851851851851851851851851851851851851851851851851851852
除:30
用字符串来控制输入,数组来存储,数组的低位存整数的低位,高位来存储高位,
和:计算的过程基本上和小学生列竖式做加法相同。
差:跟和差不多
乘:计算的过程基本上和列竖式做乘法相同。为编程方便,并不急于处理进位,而将进位问题留待最后统一处理
除:基本的思想是反复做减法,看看从被除数里最多能减去多少个除数,商就是多少。一个一个减显然太慢,如何减得更快一些呢?以7546除以23 为例来看一下:开始商为0。先减去23 的100 倍,就是2300,发现够减3
次,余下646。于是商的值就增加300。然后用646 减去230,发现够减2次,余下186,于是商的值增加20。最后用186 减去23,够减8 次,因此最终商就是328。
n的核心是要写一个大整数的减法函数,然后反复调用该函数进行减法操作。 计算除数的10倍、100 倍的时候,不用做乘法,直接在除数后面补0 即可。
void sum(char *str1,char *str2,int MAX_LEN); void substract(char *str1,char *str2,int MAX_LEN); void product(char *str1,char *str2,int MAX_LEN); void divide(char *str1,char *str2,int MAX_LEN); int main(int argc, const char * argv[]) { const int MAX_LEN = 200; char str1[MAX_LEN],str2[MAX_LEN]; scanf("%s",str1); scanf("%s",str2); printf("和:"); sum(str1,str2,MAX_LEN); printf("差:"); substract(str1,str2,MAX_LEN); printf("乘:"); product(str1,str2,MAX_LEN); printf("除:"); divide(str1,str2,MAX_LEN); return 0; } void sum(char *str1,char *str2,int MAX_LEN)//加 { // 求两个不超过100位的非负整数的和 int arr1[MAX_LEN]; int arr2[MAX_LEN]; memset(arr1,0,sizeof(arr1));//对数组进行清零 memset(arr2,0,sizeof(arr2)); int strlen1 =(int)strlen(str1); int strlen2 =(int)strlen(str2); int i,j; for(i=0,j=strlen1-1;j>=0;i++,j--)//把字符串的字符转换为数字后 arr1[i]=str1[j]-'0'; //从后往前传递给数组 for(i=0,j=strlen2-1;j>=0;i++,j--) arr2[i]=str2[j]-'0'; for(i=0;i<MAX_LEN;i++)//按位相加 { arr1[i]+=arr2[i];//数组arr1保存运算后的结果 if(arr1[i]>=10) //按10进位 { arr1[i]-=10; arr1[i+1]++;//进位 } } for(i=MAX_LEN-1;(i>=0)&&(arr1[i]==0);i--);//从数组后面往前输出,即为结果 if(i>=0) for(;i>=0;i--) printf("%d",arr1[i]); else printf("0"); printf("\n"); } void substract(char *str1,char *str2,int MAX_LEN)//减 { // 求两个不超过100位的非负整数的差 int arr1[MAX_LEN]; int arr2[MAX_LEN]; memset(arr1,0,sizeof(arr1));//对数组进行清零 memset(arr2,0,sizeof(arr2)); int strlen1 =(int)strlen(str1); int strlen2 =(int)strlen(str2); int i,j; for(i=0,j=strlen1-1;j>=0;i++,j--)//把字符串的字符转换为数字后 arr1[i]=str1[j]-'0'; //从后往前传递给数组 for(i=0,j=strlen2-1;j>=0;i++,j--) arr2[i]=str2[j]-'0'; int nStartPos=0; for(i=0;i<MAX_LEN;i++)//按位相减 { arr1[i]-=arr2[i];//数组arr1保存运算后的结果 if(arr1[i]<0) //借位 { arr1[i]+=10; arr1[i+1]--;//借位 } if(arr1[i]) nStartPos=i;//记录最高位的位置 } // for(i=MAX_LEN-1;(i>=0)&&(arr1[i]==0);i--);//从数组后面往前输出,即为结果 i=nStartPos; if(i>=0) for(;i>=0;i--) printf("%d",arr1[i]); else printf("0"); printf("\n"); } void product(char *str1,char *str2,int MAX_LEN)//乘 { // 求两个不超过100位的非负整数的积 int arr1[MAX_LEN],arr2[MAX_LEN],arr3[2*MAX_LEN]; for(int k=0;k<MAX_LEN;k++)arr1[k]=0; for(int k=0;k<MAX_LEN;k++)arr2[k]=0; for(int k=0;k<2*MAX_LEN;k++)arr3[k]=0; int i,j; int strlen1=(int)strlen(str1); int strlen2=(int)strlen(str2); for(i=0,j=strlen1-1;j>=0;i++,j--)//把字符串的字符转换为数字后 arr1[i]=str1[j]-'0'; //从后往前传递给数组 for(i=0,j=strlen2-1;j>=0;i++,j--) arr2[i]=str2[j]-'0'; for(i=0;i<strlen2;i++)//用第二个数乘以第一个数 { for(j=0;j<strlen1;j++) arr3[i+j]+=arr2[i]*arr1[j];//乘 } for(i=0;i<MAX_LEN*2;i++)//进位 { if(arr3[i]>=10) { arr3[i+1]+=arr3[i]/10; arr3[i]%=10; } } for(i=2*MAX_LEN-1;(arr3[i]==0)&&(i>=0);i--); if(i>=0) for(;i>=0;i--) printf("%d",arr3[i]); else printf("0"); printf("\n"); } void divide(char *str1,char *str2,int MAX_LEN)//除 { int divide_sub( int * p1, int * p2, int strlen1, int strlen2); int arr1[MAX_LEN]; //被除数, arr1[0]对应于个位 int arr2[MAX_LEN]; //除数, arr2[0]对应于个位 int aResult[MAX_LEN]; //存放商,aResult[0]对应于个位 //长度为 strlen1 的大整数p1 减去长度为strlen2 的大整数p2 //结果放在p1 里,返回值代表结果的长度 //如不够减返回-1,正好减完返回 0 int i, j; int strlen1 = (int)strlen( str1); memset( arr1, 0, sizeof(arr1)); memset( arr2, 0, sizeof(arr2)); memset( aResult, 0, sizeof(aResult)); for( j = 0, i = strlen1 - 1;i >= 0 ; i --) arr1[j++] = str1[i] - '0'; int strlen2 = (int)strlen(str2); for( j = 0, i = strlen2 - 1;i >= 0 ; i --) arr2[j++] = str2[i] - '0'; if( strlen1 < strlen2 ) { printf("0\n"); } int nTimes = strlen1 - strlen2; if(nTimes > 0) { for( i = strlen1 -1; i >= nTimes; i -- ) arr2[i] = arr2[i-nTimes];//朝高位移动 for( ; i >= 0; i--)//低位补0 arr2[i] = 0; strlen2 = strlen1; } for( j = 0 ; j <= nTimes; j ++ ) { int nTmp; //一直减到不够减为止 //先减去若干个 arr2×(10 的 nTimes 次方), //不够减了,再减去若干个 arr2×(10 的 nTimes-1 次方),...... while( (nTmp = divide_sub(arr1, arr2+j, strlen1, strlen2-j)) >= 0) { strlen1 = nTmp; aResult[nTimes-j]++; //每成功减一次,则将商的相应位加1 } } //下面输出结果,先跳过高位0 for( i = MAX_LEN-1; (i >= 0) && (aResult[i] == 0); i -- ); if( i >= 0) for( ; i>=0; i--) printf("%d", aResult[i]); else printf("0"); printf("\n"); } int divide_sub( int * p1, int * p2, int strlen1, int strlen2) { int i; if( strlen1 < strlen2 ) return -1; //下面判断p1 是否比p2 大,如果不是,返回-1 if( strlen1 == strlen2 ) { for( i = strlen1-1; i >= 0; i -- ) { if( p1[i] > p2[i] ) break; //p1>p2 else if( p1[i] < p2[i] ) return -1; //p1<p2 } } for( i = 0; i < strlen1; i ++ ) { //要求调用本函数确保当i>=strlen2 时,p2[i] = 0 p1[i] -= p2[i]; if( p1[i] < 0 ) { p1[i]+=10; p1[i+1] --; } } for( i = strlen1 -1 ; i >= 0 ; i-- ) if( p1[i] )//找到最高位第一个不为0 return i + 1; return 0;//全部为0,说明两者相等 }
测试:
666666666666666666666666666666666666666666666666666666666666666666
22222222222222222222222222222222222222222222222222222222222222222
和:688888888888888888888888888888888888888888888888888888888888888888
差:644444444444444444444444444444444444444444444444444444444444444444
乘:14814814814814814814814814814814814814814814814814814814814814814651851851851851851851851851851851851851851851851851851851851851852
除:30
相关文章推荐
- 蓝桥杯题目 输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。
- [置顶] 将一个长度超过100位数字的十进制非负整数转换为二进制数(大数据处理)
- 大整数相乘------输出两个不超过100位的大整数的乘积
- 华为2012校园招聘上机题——大数相乘,两个超过100位的大数相乘C语言
- 实现两个非负整数相乘
- 结构体里定义超过两个字符数
- 我在一个结构体里定义超过两个字符数组的成员输出结果会出错
- 不要在同一客户端同时使用超过两个的 HTTP 长连接
- 让win2003突破两个人同时远程登录的限制,由于2003默认情况下远程连接只能允许两个用户同时登录,超过两人同时登录就会提示:终端服务器超出最大连接数。。
- 二、 编写函数int stat(int a[],int n,int c[][2])。a指向的数组中保存了由n个1位整数组成的数列(n为偶数)。函数从前至后依次将a数组中每两个相邻元素拼成一个不超过2位
- 给定一个非负整数,你可以最多交换两个数字一次来获得最大值的数字。 返回您可以获得的最大值。
- 给出两个正整数A和B,计算A*B的值。保证A和B的位数不超过500位。
- Leetcode第二题,用链表实现两个非负整数求和
- C#实现用欧几里德算法、连续整数检测算法、公因数算法求两个非负整数的最大公约数
- 给出两个正整数A和B,计算A+B的值。保证A和B的位数不超过500位
- 面试题七 C/C++ 两个字符串由数字组成的相加,最大不超过32bit整形的系统函数--程序员面试题
- 欧几里得算法求两个非负整数的最大公因子
- Java求解两个非负整数最大公约数算法【循环法与递归法】
- 如何用perform selector调用超过两个以上参数的方法
- 写出执行双旋转的函数,其效率要超过执行两个单旋转