大整数的加法和乘法运算
来源:互联网 发布:java -jar 参数 编辑:程序博客网 时间:2024/06/10 16:36
C和C++中整数最大只能表示10位,不然就会溢出,所以出现了如何避免整数溢出的问题。其中一个方法就是使用字符串来表示,使用字符串的长度是没有限制的。
使用字符串表示整数然后进行乘法运算的关键有如下几点:
- 被乘数和乘数相乘时最开始不处理进位,而是每一位相乘的计算结果都是用整数来保存
- 第一步计算完毕之后从低位到高位开始处理进位
- 不难发现保存计算结果的整型数组的长度是被乘数的长度和乘数的长度之和
- 注意最高位的进位问题
- 将计算完毕后的整形数组转换成字符数组
- 字符数组尾端记得加上\0,整型转字符型时记得加上'0'
基本的算法步骤使用下面的图示来说明:(下面都是针对正整数的运算)
代码实现如下:
// Test9.cpp : 定义控制台应用程序的入口点。//#include <iostream>#include <assert.h>#include <sstream>using namespace std;void multiply(const char * str1,const char * str2){assert(str1!=NULL&&str2!=NULL);int cstr1=strlen(str1);int cstr2=strlen(str2);int * res=new int[cstr1+cstr2]();//注意new关键词尾端加上小括号就会将res初始化为0,特别注意小括号里不能填任何初值//逐位处理,处理遍历字符串是从低位到高位,那么运算结果就是从整数的高位开始计算for (int i=0;i<cstr1;i++){for (int j=0;j<cstr2;j++){res[i+j+1]+=int(str1[i]-'0')*int(str2[j]-'0');//首先计算的是高位,res要加上1是为了处理后面的偏移}}//处理进位for (int i=cstr1+cstr2-1;i>=1;i--){if(res[i]>=10){res[i-1]+=res[i]/10;res[i]=res[i]%10;}}//将int型数组保存成字符数组char * ans=new char[cstr1+cstr2];int k=0;while(res[k]==0)//首先需要掉过为0的那些高位k++;int pos=0;while(k<cstr1+cstr2)//执行复制操作{ans[pos++]=res[k++]+'0';//不要忘记了加上'0'}ans[pos]='\0';//最后记得字符数组尾端需要补上字符串结束标记cout<<"计算结果为:";for (int i=0;i<strlen(ans);i++){cout<<ans[i];}cout<<endl;delete [] res;delete [] ans;}int main(){string s;stringstream ss;cout<<"输入两个数,以空格隔开:"<<endl;while(getline(cin,s)){ss.clear();ss<<s;string s1,s2;ss>>s1>>s2;multiply(s1.c_str(),s2.c_str());}getchar();return 0;}
测试输出:
同样的思路可以处理大整数的加法:
关键的函数如下:
void add(const char * str1,const char * str2){assert(str1!=NULL&&str2!=NULL);int cstr1=strlen(str1);int cstr2=strlen(str2);int maxLen=max(cstr1,cstr2)+1;int * res=new int[maxLen]();int minLen=min(cstr1,cstr2);int k=0;int i=cstr1-1,j=cstr2-1 ;//从字符串尾端开始遍历起,将结果保存在res数组中for (;i>=0&&j>=0;i--,j--){res[k]=str1[i]-'0'+str2[j]-'0';k++;}//对于较长的字符串,直接将它添加到res尾端即可while (i>=0)res[k++]=str1[i--]-'0';while(j>=0)res[k++]=str2[j--]-'0';//处理进位for (int m=0;m<maxLen-1;m++){res[m+1]+=res[m]/10;res[m]=res[m]%10;}//将结果集的高位去除k=maxLen-1;while(res[k]==0)k--;char * ans=new char[maxLen];int m=k,n=0;//需要从res数组中从高位开始取数for (;m>=0;m--,n++){ans[n]=res[m]+'0';}ans[n]='\0';cout<<"计算结果为:"<<ans<<endl;}
测试输出:
0 0
- 大整数的加法和乘法运算
- 大整数的加法、减法和乘法
- 大整数运算之 大整数加法、减法、乘法
- 关于大整数乘法和加法的一些整理
- 大整数的加法运算
- 大整数加法和乘法STL
- 大整数的乘法、加法、减法
- 大整数的乘法与加法
- 大整数的乘法运算
- 大整数的乘法运算
- 大整数的乘法运算
- Java 实现大整数加法、乘法、阶乘运算
- 大精度整数三种运算(加法,减法,乘法)
- Problem B: 大整数的加法运算
- Problem I: 大整数的加法运算
- Problem A: 大整数的加法运算
- 一元多项式的加法和乘法运算
- 分块矩阵的加法和乘法运算
- Android典型界面设计(6)——ActionBar Tab+ViewPager+Fagment实现滑动导航
- Java 程序优化:字符串操作、基本运算方法等优化策略
- 在Web 应用的生命周期中,ServletContext 对象最早被创建,最晚被销毁。
- 关于几个好的博客
- 低功耗蓝牙开发技术概述(二)——控制器(上)
- 大整数的加法和乘法运算
- 稳定排序和不稳定排序
- qwt6.1.0编译与安装
- JavaSE 揭秘枚举类型
- HDU 3342 Legal or Not (拓扑排序)
- [leetcode][two pointers] Minimum Size Subarray Sum
- 线程同步与互斥:互斥锁
- R语言_图形初阶
- Gson在 Android开发中可能存在的陷阱