高精除以高精

高精除以高精,求它们的商和余数。
【算法分析】
高精除以低精是对被除数的每一位(这里的“一位”包含前面的余数,以下都是如此)都除以除数。
高精除以高精则是用减法模拟除法,对被除数的每一位都减去除数,一直减当前位置的数字(包含前面的余数)小于除数(由于每一位的数字小于10,所以对于每一位最多进行10次计算),具体实现< 方法一 >:

#include<iostream>
#include<cstring>
using namespace std;
int a[101],b[101],c[101],d,i;
void init(int a[]){//获取字符串 并将字符串逆向存储转换为数组  
	string s;
	cin>>s;
	a[0]=s.length();//a[0]储存字符串的长度 
	for(i=1;i<=a[0];i++)
		a[i]=s[a[0]-i]-'0';
}
void print(int a[]){//打印函数 逆向输出 
	if(a[0]==0) {
		cout<<0<<endl;
		return ;
	}
	for(int i=a[0];i>0;i--) cout<<a[i];
	cout<<endl;
	return ;
} 
int compare(int a[],int b[]){//比较函数 a>b返回1;a<b返回-1;a=b返回0
	if(a[0]>b[0]) return 1;
	if(a[0]<b[0]) return -1;
	for(int i=a[0];i>0;i--){//从高位向低位比较 
		if(a[i]>b[i]) return 1;
		if(a[i]<b[i]) return -1;
	}
	return 0;//每一位都相等 
} 
void jian(int a[],int b[]){
	int flag,i;
	flag=compare(a,b);
	if(flag==0) {a[0]=0;return;}
	if(flag==1){
		for(i=1;i<=a[0];i++){
			if(a[i]<b[i]){//处理借位 
				a[i+1]--;
				a[i]+=10;
			} 
			a[i]-=b[i];
		}
		while(a[0]>0&&a[a[0]]==0) a[0]--;//修正位数 
		return;
	}
}
void numcpy(int p[],int q[],int det){//将p数组拷贝到q数组中,从q的det位置开始 
	for(int i=1;i<=p[0];i++)q[i+det-1]=p[i];
	q[0]=p[0]+det-1;//更新q的位数 
}
void chu(int a[],int b[],int c[]){//除法运算函数 
	int i,tmp[101];
	c[0]=a[0]-b[0]+1;//确定商的位数 
	for(i=c[0];i>0;i--){
		memset(tmp,0,sizeof(tmp));
		numcpy(b,tmp,i);
		while(compare(a,tmp)>=0){//减法模拟除法运算过程 
			c[i]++;
			jian(a,tmp);	
		}
	}
	while(c[0]>0&&c[c[0]]==0) c[0]--;
	return ;
} 
int main()
{
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	init(a);
	init(b);
	chu(a,b,c);
	print(c);
	print(a);
	return 0;
}

< 方法二 >:

#include <iostream>
#include <string.h>
#include <algorithm> 
using namespace std;
#define MAX 400

void IntToChar(int Arr[],char str[],int begin,int end){
	for(int i=begin;i<end;i++)	str[i]=Arr[i]+'0';	
	str[end]='\0';
}
void CharToInt(char str[],int Arr[]){
	int i=0;
	while(str[i]!='\0')	Arr[i]=str[i++]-'0';
}
void swap(int &a,int &b){
	int t=a;a=b;b=t;
} 
void filterZero(char a[]){
	int l;
	while(a[0]=='0' && a[1]!='\0')	{
		l=strlen(a);
		for(int i=0;i<l;i++)	a[i]=a[i+1];
	}
}
void sub( char s1[], char s2[],char s3[])
{
	char a[MAX]={0},b[MAX]={0};
	int ia[MAX]={0},ib[MAX]={0},ic[MAX]={0};
	int size,la,lb;
	bool flag = false; //符号位
	filterZero(s1),filterZero(s2);
	la=strlen(s1),lb=strlen(s2);
	if(la<lb ||(la==lb && strcmp(s1,s2)<0)){
		flag = true;  //结果为负数
	    strcpy(a,s2),strcpy(b,s1); //复制被减数和减数 
	    swap(la,lb);
	}
	else 	strcpy(a,s1),strcpy(b,s2); //复制被减数和减数 
	size = la>lb?la:lb;
	reverse(a,a+la),reverse(b,b+lb);
	CharToInt(a,ia);
	CharToInt(b,ib);
	//减法
	for(int i=0;i<size;i++){
		ic[i]+=ia[i]-ib[i];
		if(ic[i]<0){
			ic[i+1]--;
			ic[i]+=10;
		}
	}
	//输出
	bool bOut=false;
	int k=0;
	if(flag)  s3[k++]='-';
 	for(int i=size;i>=0;i--){
 		if(ic[i]) bOut = true;
 		if(bOut) s3[k++]=ic[i]+'0';
 	}
 	//正好为0的情况
	if(k==0) s3[k++]='0'; 
 	s3[k]='\0';
} 
int main(int argc, char *argv[])
{
	char a[MAX]={0},b[MAX]={0};
	int c[MAX]={0};
	char bcx[MAX],bk[MAX];
	int size,la,lb,k;
	cin>>a>>b;
	la=strlen(a),lb=strlen(b);
	//特殊情况不够除直接输出结果
	if(la<lb || (la==lb && strcmp(a,b)<0))
	{
		cout<<"0"<<endl<<a<<endl;
		return 0;
	} 
	size=la-lb+1; //确定除的次数 
	//除法模拟 
	for(int i=0;i<size;i++){
		if(i==0){
			strncpy(bcx,a,lb); //根据除数的长度确定开始的被除数 
			bcx[lb]='\0'; 
		}	
		else{
			k=strlen(bcx);
			bcx[k]=a[lb+i-1],bcx[k+1]='\0';
		}
		//尝试减法 
		k=0;
		sub(bcx,b,bk);  //bk为高精度减法结果数据 
		while(bk[0]!='-'){
			k++;
			strcpy(bcx,bk); //将减的结果更新为被减数 
			sub(bcx,b,bk);  //继续尝试减法 
		}
		c[i]=k; //保存结果
	}
	//输出商
	bool bOut=false;
	for(int i=0;i<size;i++){
		if(c[i]) bOut = true;
		if(bOut) cout<<c[i];
	}
	//输出余数 
	cout<<endl<<bcx<<endl;
	
	return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宏阳李老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值