今天主要学习:
1.复习高精度
高精度基本结构:开数组存每一位,模拟字符串。
思想:
1)数据接收与储存
由于我字符串经常搞错区间两端,所以我习惯需要被计算的数与计算结果都开数组储存。(字符串是计已经给定的大数,数组是从小整数迭代起来的)
void init(int a[]) { //字符串记法, 传入数组
string s;
cin >> s;
len = s.length(); // s.length --> 计算字符串位数
for(int i=1; i<=len; i++)
a[i] = s[len -i] - '0'; //将字符串s转换为数组a, 倒序存储
}
2)数据的迭代部分,设数组origin1[],origin2[],changed[]。
1:加减乘除的计算
加:直接用oringin的每一位加得到changed。
进位问题:
if(changed[i] >= 10) {
changed[i] %= 10;
++changed[i++];
}
减:借位问题
if(origin1[i] < oringin2[i]) {//设origin1-origin2
--origin1[i+1];
origin1[i] += 10;
}
乘:
//从别人那里偷的图
changed[ i + j ]=origin1[ i ]*origin2[ j ]+jw+changed[ i + j ];
//origin1[j]+origin2[i],如果图中c数组从1开始,那么changed[ i + j +1 ]
jw=changed[ i + j ]/10;
changed[ i + j ]%=10;
其中jw表示从前一次运算(后一位)得到的进位。
除:
①低精
string origin_s; //被除数 a 的字符型
reminder=0; //余数 reminder 一定要初始化
len=origin_s.length(); // a长度
for(i=0;i<len;i++){ //转化为 int 型数组
origin[i]=origin_s[len-1-i]-'0';
}
for(i=len-1;i>=0;i--){ //核心计算
reminder=reminder*10+origin[i]; //模拟竖式除法中的落位
changed[i]=reminder/b;
reminder%=b;
}
②高精
//从别人那偷的
#include <iostream>
#include <string>
using namespace std;
bool judge(int* a,int* b,int len){ //判断len长度的 b 是否可以被 a 除
if(a[len]>0) return true; //如果 a 比 b 长, 一定可以除
for(int i=len-1;i>=0;i--){//从 a 的最高位开始比
if(a[i]>b[i]) return true;//除去相等位的最高位大于b,说明a比b大,可以除
else if(a[i]<b[i]) return false;//除去相等位的最高位小于b,说明a比b小,不可以除
}
return true;//a和b完全一样,可以除
}
int main(){
string a_s,b_s;
int a[521]={0},b[521]={0},ans[521]={0};
int i,j,len_a,len_b,len;
cin>>a_s>>b_s;
if(b_s=="0"){//除数不能为0
cout<<"除数不能为0"<<endl;
return 0;
}
len_a=a_s.length();//计算 a和 b的长度
len_b=b_s.length();
len=len_a-len_b; //结果最开始的下标
for(i=0;i<len_a;i++) a[i]=a_s[len_a-1-i]-'0';//字符型转int型
for(i=0;i<len_b;i++) b[i]=b_s[len_b-1-i]-'0';
for(i=len_a-len_b;i>=0;i--){
while(judge(a+i,b,len_b)){//当a可以被b减的时候一直进行,直到不能被减,即得到最终的商
ans[i]++; //记录a被b减的次数,即为除法的结果
for(j=0;j<=len_b-1;j++){//高精度减法的实现方法
if(a[i+j]<b[j]){
a[i+j+1]--;
a[i+j]+=10;
}
a[i+j]-=b[j];
}
}
}
while(a[len_a]==0&&len_a>0) len_a--;//去掉前缀无用的零
while(ans[len]==0&&len>0) len--;
for(i=len;i>=0;i--) cout<<ans[i];//输出结果
if(len<0) cout<<"0";//当被除数短于除数时,len<0不进行上一条语句,单独输出一个零
if(len_a>1||a[0]>0){//a最后没有减完的部分成为余数,余数为0就不输出
cout<<"余";
for(i=len_a;i>=0;i--) cout<<a[i];
}
}