补题日寄3

今天主要学习:

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];
	} 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值