(C语言实现)高精度除法 (洛谷 P2005 A/B Problem II)

前言
本期我们分享用C语言实现高精度除法,可通过该题测试点我点我,洛谷 p2005
那么话不多说我们开始吧。
在这里插入图片描述
讲解
大家还记不记得小学的时候我们是怎么做除法的?我们以111÷5为例。
在这里插入图片描述

我们的高精度除法也将采用这个思路进行,分别用两个数组储存数字a和b的值,翻转后,从相对最高位开始相除,虽然我们不好实现除法,但是我们可以实现减法,比如11÷5可以理解为11-5-5这样商就是2余数就是1,也就是所我们可以弄一个减法的循环直到不能再减就退出循环。那么我们在相减之前就需要判断两者的大小,比如1和5明显没法再减了,我们就需要跳到下一位再重新进行减法循环。
大致的思路就是这样,下面我们用代码讲解:

#include <stdio.h>
#include<string.h>
char arra[20000] = { 0 }, arrb[20000] = { 0 };//分别储存a,b的值
int ans[20000] = { 0 };//储存商
int judge(char* arr1, char* arr2, int len)//判断是否可以相减的函数
{
    if (arr1[len] >'0') return 1; //如果arr1比arr2长, 则可以除 
    for (int i = len - 1; i >= 0; i--) {//从arr的最高位开始与arr2比较 
        if (arr1[i] > arr2[i]) return 1;//相同位时arr1中的数字更大,则可以相除
        else if (arr1[i] < arr2[i]) return 0;//相同位时arr1数字更小则不能相除
    }
    return 1;//arr1和arr2完全一样,可以相除 
}
void my_reverse(char* arr, int len)//翻转函数
{
    for (int i = 0; i < len - 1; i++, len--)
    {
        char temp = arr[i];
        arr[i] = arr[len - 1];
        arr[len - 1] = temp;
    }
}
void print_div(int len1, int len2, char* arr1, char* arr2, int* ans)
{
    for(int i = len1-len2;i>=0;i--)//从最高位开始
    {
        while (judge(arr1 + i, arr2, len2))//判定是否可以相减
        {
            for (int j = 0; j < len2; j++)//高精度减法
            {
                if (arr1[i + j] < arr2[j])
                {
                    arr1[i + j + 1] -= 1;
                    arr1[i + j] += 10;
                }
                arr1[i + j] -= (arr2[j] - '0');
            }
            ans[i]++;//ans[i]不可能>10
        }
    }
    int len_ans = len1 - len2;//ans的长度
    while (arr1[len1] == '0' && len1 > 0) len1--;//去掉前缀无用的零 
    while (ans[len_ans] == 0 && len_ans > 0) len_ans--;
    for (int i = len_ans; i >= 0; i--)//打印商
    {
        printf("%d", ans[i]);
    }
    printf("\n");
    //如果想要得到余数,则直接打印arr1即可,此时arr1存储的正是余数需要余数直接把下面的注释消掉即可
    //if (len1 > 0||arr1[0]>='0')
    //  for (int i = len1 - 1; i >= 0; i--)
    //      printf("%c", arr1[i]);
}
int main()
{

    scanf("%s %s", arra, arrb);
    int lena = strlen(arra);//计算a和b的长度
    int lenb = strlen(arrb);
    my_reverse(arra, lena);
    my_reverse(arrb, lenb);
    print_div(lena, lenb, arra, arrb, ans);
    return 0;
}
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小马的Trainer

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

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

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

打赏作者

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

抵扣说明:

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

余额充值