【第七篇blog】专题:高精度计算<上>
来源:互联网 发布:网络视频节目许可证 编辑:程序博客网 时间:2024/06/06 12:48
专题篇:高精度
——————————————————————我是更新提示分割线———————————————————————
<第一次更新>仅供学习使用
—————————————————————我是华丽丽的正文分割线——————————————————————
高精度计算是一种用来处理大数据的算法,一般超过longlong的数据计算就需要使用高精度算法,上篇主要讲加法和减法。
加法
引入:A+B Problem
题目描述
高精度加法,相当于a+b problem,不用考虑负数
输入输出格式
输入格式:
分两行输入a,b<=10^1000
输出格式:
输出只有一行,代表A+B的值
解析:看似简单的题目,但数据量非常大,这时,就不可能用直接计算来实现了。
思考1):怎样储存数据?
对于大数据,可以采用字符串输入,转换为数组储存,每一个下标所在的位置储存一位数字,就可以方便的储存大数据了。
因此,我们有如下函数代码:
void scan(){ cin>>s>>s1; for(i=0;i<=s.size();i++)a[i]=int(s[i]-'0');//将字符的数字转换为数字的值 for(i=0;i<=s1.size();i++)b[i]=int(s1[i]-'0');}
思考2):怎样计算?
对于计算,有了数组储存,我们很容易就能想到逐位相加,实际就是模拟我们小学中的列竖式计算。
但是,如果使用这种计算方式,对于最高位储存在最前面的数组,进位的处理就会变得相当麻烦,必须将储存方式推翻重来
所以,储存方式为逆序储存,方便进位处理。又有如下代码
void scan(){ cin>>s>>s1; for(i=0;i<=s.size();i++)a[s.size()-i]=int(s[i]-'0');//将当前数字储存到a,b数组的末端 for(i=0;i<=s1.size();i++)b[s1.size()-i]=int(s1[i]-'0');}
这样,我们就能实现计算的基本代码了
void initi(){ for(i=1;i<=1001;i++) { c[i]=b[i]+a[i]; } }
思考3):怎样处理进位?
对于进位,直接采用数组的求余,加减就很容易实现
计算代码能做如下更改
void initi(){ for(i=1;i<=1001;i++) { c[i]=c[i]+b[i]+a[i]; c[i+1]=c[i]/10;//进位处理:当然,c[i]不足10时,c[i]/10=0,c[i]%10=c[i] c[i]=c[i]%10; } }
到这里为止,高精度加法的计算已经大体实现,最后一步时输出,不要忘记储存时是逆序储存的,输出时去掉数组末尾的0,逆序输出即可
代码如下
void print(){ while(c[maxx]==0&&maxx>1)maxx--; for(i=maxx;i>=1;i--) { cout<<c[i]; }}
将各个函数组合,高精度加法的代码就能实现了
#include<bits/stdc++.h>using namespace std;int i,j,maxx=1001;string s,s1;int a[1050]={},b[1050]={},c[1050]={};void scan()//输入{ cin>>s>>s1; for(i=0;i<=s.size();i++)a[s.size()-i]=int(s[i]-'0'); for(i=0;i<=s1.size();i++)b[s1.size()-i]=int(s1[i]-'0');}void initi()//计算{ for(i=1;i<=1001;i++) { c[i]=c[i]+b[i]+a[i]; c[i+1]=c[i]/10; c[i]=c[i]%10; } }void print()//输出{ while(c[maxx]==0&&maxx>1)maxx--; for(i=maxx;i>=1;i--) { cout<<c[i]; }}int main(){ scan(); initi(); print(); return 0;}
减法
引入:A-B Problem
输入输出格式
输入格式:
两个整数a,b(第二个可能比第一个大)
输出格式:
结果(是负数要输出负号)
对于高精度减法,又有几个新的问题
思考1):怎样处理负数?
对于负数的处理,如果b>a,我们能直接输出一个负号,再交换a,b进行计算即可。
因此,我们首先需要一个比较两个高精度数的大小的函数,思路就是先比较长度,如果相同,再从高位到低位逐位比较。
int bigger(int k,int l)//k,l代表s1,s2的当前比较位{ if(k==1&&l==1&&s1[k]==s2[l])return 0; if(s1.size()>s2.size())return 1; else { if(s2.size()>s1.size())return 2; else { if(s1[k]>s2[l])return 1; else { if(s2[l]>s1[k])return 2; else { return bigger(k-1,l-1); } } } }} //返回1代表s1大,返回2代表s2大,返回0代表两数完全相等
这样,我们就能构成交换函数了
void change(){ if(bigger(s1.size(),s2.size())==2)//比较两数 { cout<<"-"; s3=s1; s1=s2; s2=s3; }}
思考2):怎样处理借位?
借位的处理实际和进位相似,只需将当前位加10,下一位减1即可
void initi(){ for(i=1;i<=s1.size();i++) { c[i]=c[i]+a[i]-b[i]; if(c[i]<0)//借位处理 { c[i]+=10; c[i+1]--; } }}
处理完这两个问题,高精度减法也基本完成了,组合输入输出就能构成代码。
#include<bits/stdc++.h>using namespace std;int i,j,maxx=10005;string s1,s2,s3;int a[10005]={},b[10005]={},c[10005]={};void scan()//输入{ cin>>s1>>s2; for(i=0;i<=s1.size();i++)a[s1.size()-i]=int(s1[i]-'0'); for(i=0;i<=s2.size();i++)b[s2.size()-i]=int(s2[i]-'0');}int bigger(int k,int l)//比较{ if(k==1&&l==1&&s1[k]==s2[l])return 0; if(s1.size()>s2.size())return 1; else { if(s2.size()>s1.size())return 2; else { if(s1[k]>s2[l])return 1; else { if(s2[l]>s1[k])return 2; else { return bigger(k-1,l-1); } } } }} void change()//交换{ if(bigger(s1.size(),s2.size())==2) { cout<<"-"; s3=s1; s1=s2; s2=s3; }}void print()//输出{ while(c[maxx]==0&&maxx>1)maxx--; for(i=maxx;i>=1;i--) { cout<<c[i]; }}void initi()//计算{ for(i=1;i<=s1.size();i++) { c[i]=c[i]+a[i]-b[i]; if(c[i]<0) { c[i]+=10; c[i+1]--; } }}int main(){ change(); scan(); initi(); print(); return 0;}
到此为止,高精度的简单计算:加法,减法就实现了。
—————————————————————我是华丽丽的正文分割线——————————————————————
提示:下篇讲高精乘除
附件:高精运算模板,用于验证自己的程序是否准确
链接:https://pan.baidu.com/s/1bo9YN87
password:p0du
选择需要的高精计算,删除注释即可。
——————————————————————我是讲废话的分割线———————————————————————
- 【第七篇blog】专题:高精度计算<上>
- *高精度专题
- 高精度计算篇1
- 高精度计算篇2
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- 高精度计算
- Java集合:HashMap源码剖析
- 【转】 设置Ubuntu上的MySQL可以远程访问
- Win10x64下Vbox安装Ubuntux64共享文件夹报错:/sbin/mount.vboxsf: mounting failed with the error: Protocol error
- 文字编码系统笔记(ASCII、UNICODE、UTF-8、ANSI)
- CMake入门使用(三)动态库、静态库的编译及使用
- 【第七篇blog】专题:高精度计算<上>
- Android学习随笔(15)------网络技术
- 新手对于是否能学好seo的疑惑
- 修改Tomcat服务器Response Header中server内容
- Python系统学习系列——linux读书笔记(2)
- MANIFEST.MF说明
- 探究Struts2运行机制:StrutsPrepareAndExecuteFilter 源码剖析
- Java 修饰符(Modifier)声明顺序
- 数据结构-树的基础代码