高精除以高精,求它们的商和余数。
【算法分析】
高精除以低精是对被除数的每一位(这里的“一位”包含前面的余数,以下都是如此)都除以除数。
高精除以高精则是用减法模拟除法,对被除数的每一位都减去除数,一直减当前位置的数字(包含前面的余数)小于除数(由于每一位的数字小于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;
}