1308:【例1.5】高精除
时间限制: 1000 ms 内存限制: 65536 KB
提交数:25526 通过数: 12451
【题目描述】
高精除以高精,求它们的商和余数。
【输入】
输入两个低于300位的正整数。
【输出】
输出商和余数。
【输入样例】
1231312318457577687897987642324567864324567876543245671425346756786867867867
1231312318767141738178325678412414124141425346756786867867867
【输出样例】
999999999748590
179780909068307566598992807564736854549985603543237528310337
#include <bits/stdc++.h>
using namespace std;
char str1[305];//字符串储存 被除数
char str2[305];//字符串储存 除数
int temp[305];//补齐0后 临时数组
int num1[305];//数组储存 被除数
int num2[305];//数组储存 除数
int ans[305]; //数组储存 商
void numcpy(int *num1,int *num2,int dest)//补齐函数
{
//右移 左边空出dest个位置 补齐0
for(int i=1;i<=num1[0];i++)//num1实际上代表除数
{
num2[i+dest-1]=num1[i];//num2实际上代表temp
}
num2[0]=num1[0]+dest-1;//temp数组变更长度
}
int compare (int *num1,int*num2)//比较函数
//引入 被除数 除数
{
//一 比较数字长度
if (num1[0]<num2[0])//除数 大于 被除数
{
return -1;
}
else if (num1[0]>num2[0])//被除数 大于 除数
{
return 1;
}
//二 数字长度相同 比较每一位
for(int i=num1[0];i>0;i--)//高-低位 循环比较
{
if (num1[i]<num2[i])//除数 大于 被除数
{
return -1;
}
else if (num1[i]>num2[i])//被除数 大于 除数
{
return 1;
}
}
return 0;//大小相同
}
int main()
{
cin >> str1;//被除数 字符串输入
cin >> str2;//除数 字符串输入
//处理正负
bool flag1=false;//储存num1正负
if (str1[0]=='-')//输入str1有负号
{
flag1=true;//储存num1为负数
strcpy(str1,&str1[1]);//覆盖负号
}
bool flag2=false;//储存num2正负
if(str2[0]=='-')//输入str2有负号
{
flag2=true;//储存num2为负数
strcpy(str2,&str2[1]);//覆盖负号
}
//数据倒序
int len=strlen(str1);//测量 被除数 长度
num1[0]=len;//预留 num1第0位 储存 被除数长度
for (int i=0;i<len;i++)//倒序 转数组
{
num1[len-i]=str1[i]-'0';
}
len=strlen(str2);//测量 除数长度
num2[0]=len;//同上
for (int i=0;i<len;i++)//倒序 转数组
{
num2[len-i]=str2[i]-'0';
}
if (compare(num1,num2)==0)//被除数=除数
{
cout << 1 << endl << 0 << endl;
//打印 商=1 余数=0
return 0;
}
else if (compare(num1,num2)==-1)//除数 大于 被除数
{
//商=0 余数为被除数
cout << 0 << endl;//输出商
if (flag1)//被除数=余数 为负数
{
cout << "-";//输出负号
}
cout << str1 << endl;//输出 被除数字符串 已去负号
}
else//被除数 大于 除数
{
ans[0]=num1[0]-num2[0]+1;//商预计长度
for (int i=ans[0];i>0;i--)//倒序处理答案
{
//利用临时数组temp补0对齐
memset (temp,0,sizeof(temp));//初始化temp为0
numcpy(num2,temp,i);//除数放入临时数组进行对齐
//逐步进行减运算 当 temp 小于 被除数 一直减
while(compare(num1,temp)>=0)
//被除数大于temp进行运算
{
ans[i]++;//商加1
// cout << "dfafadsf" << endl;
for(int j=1;j<=num1[0];j++)//逐步进行减运算
//循环 被除数长度 次
{
if (num1[j]<temp[j])//判断是否需要进位
{
num1[j+1]--;
num1[j]+=10;//进位
}
num1[j]-=temp[j];//被除数-除数
}
int tempk=num1[0];//定义临时 被除数位数
while(num1[tempk]==0)//判断高位是否为0
{
tempk--;//临时位数变短
}
num1[0]=tempk;//变更被除数位数
}
}
}
//运算完成输出结果
while(ans[0]>0&&ans[ans[0]]==0)//去除前导0
//商不为0 有前导0
{
ans[0]--;//位数变短 不输出前导0
}
//打印商 余数
if (!flag1 && flag2 || flag1 && !flag2)//被除数 除数有一个为负数->商为负数
{
cout << "-";//输出负数
}
for(int i=ans[0];i>0;i--)//倒序输出商
{
cout << ans[i];
}
cout << endl;//换行
if (num1[0]==0)//被除数无剩余=无余数
{
cout << 0 << endl;
return 0;
}
else//有余数
{
if(flag1)//被除数剩余=余数 为负数
{
cout << "-";//输出负号
}
for (int i=num1[0];i>0;i--)//倒序输出余数
{
cout << num1[i];
}
cout << endl;
}
return 0;
}
这段代码很长且不好理解 一定要搞清楚 很重要