C++之大数相除

1.问题描述

两个大数相除。输入是两个长的字符串,实现两个数的相除。得到结果的商和余数。
例如:
输入:

2345678910
345678910

输出结果是:

6 271605450

2.代码(分析在代码中)

#include<iostream>
#include <sstream>
using namespace std;
//比较两个字符串前者是否大于等于后者
bool Compare(string first,string second)
{
    int len1=first.size();
    int len2=second.size();
    if(len1<len2)
        return false;
    else if(len1==len2 && first<second)
        return false;
    return true;
}

string sub(string num1,string num2)
{
    //fushu用来判断最后结果是否是负数
    bool fushu = false;
    //如果被减数位数小于减数,那么结果是负数,同时两个字符串交换顺序,大的数减小的数
    if(num1.size()<num2.size())
    {
        string temp = num1;
        num1 = num2;
        num2 = temp;
        fushu = true;
    }
    //两个数长度一样,这个时候,需要判断哪个数更大,如果被减数小于减数,那么结果是负数,同时两个字符串交换顺序,大的数减小的数
    else if(num1.size() == num2.size())
    {
        int len = num1.size();
        for(int i=0;i<len;++i)
        {
            if(num1[i] == num2[i])
                continue;
            if(num1[i]>num2[i])
                break;
            if(num1[i]<num2[i])
            {
                string temp = num1;
                num1 = num2;
                num2 = temp;
                fushu = true;
            }
        }
    }
    int lenNum1 = num1.size();
    int lenNum2 = num2.size();

    //用来保存结果
    int* result = new int[lenNum1];
    int index = 0;
    //num1 31 num2 29 result 1,3
    //把被除数的结果先放到result中
    for(int i=lenNum1-1;i >=0;--i)
        result[index++]=num1[i]-'0';

    //进行减法操作
    index = 0;
    for(int i=lenNum2-1;i>=0;--i)
    {
        int num = num2[i]-'0';
        //如果减数 大于 被减数,则需要退位
        if(num>result[index])
        {
            result[index+1] -=1;
            result[index] = 10+result[index] - num;
        }
        //直接相减
        else
            result[index] = result[index] - num;

        ++index;
    }
    //清除result尾部的0,index从右到左遍历,直到第一个不是0为止
    index = lenNum1-1;
    while(result[index] == 0)
        --index;


    //使用stringstream流,方便把数组输出到字符串中
    ostringstream osstr;
    //判断是否结果是负数
    if(fushu == true)
        osstr<<'-';
    for(int i=index;i>=0;--i)
        osstr<<result[i];
    delete result;
    return osstr.str();
}
void div(string a,string b)
{
    //result为商,s为余数
    string s;
    ostringstream result;
    int count,i;
    if("0"==b)
    {
        //cout<<"Error,divisor can not be zero!"<<endl;
        cout<<"NULL"<<endl;
        return;
    }

    //这部分代码是去除字符串开始的字符0
    {
        int index=0;
        while('0'==a[index])
            index++;
        //去掉字符串前缀0
        a.erase(0,index);
        index=0;
        while('0'==b[index])
            index++;
        //去掉字符串前缀0
        b.erase(0,index);
    }

    //如果被除数小于除数,那么商为0,余数为被除数
    if(!Compare(a,b))
    {
        cout<<0<<" "<<a<<endl;
        return;
    }
    int len=a.size();
    //模拟除法过程
    for(int i=0;i<len;i++)
    {
        count=0;
        s.push_back(a[i]);
        while(Compare(s,b))
        {
            //借助大数相减函数来做除法
            s=sub(s,b);
            //统计被减次数
            count++;
        }

        //因为是模拟除法,count不会大于9的
        if(count != 0)
            result<<count;    //s>b时加每次相除得到的商或者,s<b时补0
    }

    //cout<<"商为:"<<result<<",余数: "<<s<<endl;
    cout<<result.str()<<" "<<s<<endl;
}

int main()
{
    string str1,str2;
    while(cin>>str1>>str2)
        //cout<<subtraction(str1,str2)<<endl;
        div(str1,str2);
    return 0;
}

3.测试

输入:

5044
123

输出:

41 1

输入:

2345678910
345678910

输出:

6  271605450

4.总结

其实大数相除,就是一个不断相减的过程,这个相减需要从高位减到低位。其中还有一个关键就是我们需要借助大数相减这个函数,我们才好模拟相减。还需要一个函数判断我们被减数是否>=减数,这样我们就可以很好的手工模拟除法过程了。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值