当前位置:首页 > 题解目录 > 正文内容

【题解】大整数减法

亿万年的星光5年前 (2021-05-02)题解目录17144

【题目描述】

求两个大的正整数相减的差。

【输入】

共2行,第1行是被减数a,第2行是减数b(a > b)。每个大整数不超过200位,不会有多余的前导零。

【输出】

一行,即所求的差。

【输入样例】

9999999999999999999999999999999999999

9999999999999

【输出样例】

9999999999999999999999990000000000000


【参考答案】


1.基础版:char数组

#include<iostream>  
#include<cstring>  
#include<string>  
using namespace std;  

int main()  
{  
    char str1[256],str2[256],temp[256];  
    int a[256],b[256],c[256];  
    int lena,lenb,lenc;  
    int i;  

    memset(a,0,sizeof(a));  
    memset(b,0,sizeof(b));  
    memset(c,0,sizeof(c));  

    cin>>str1;//输入被减数  
    cin>>str2;//输入减数  

    lena=strlen(str1);  
    lenb=strlen(str2);  

    // 修正:明确判断被减数小于减数(长度更小,或长度相等且字典序更小)
    bool is_negative = false;
    if( (lena < lenb) || (lena == lenb && strcmp(str1, str2) < 0) )  
    {  
        // 交换被减数和减数
        strcpy(temp, str1);  
        strcpy(str1, str2);  
        strcpy(str2, temp);  
        is_negative = true; // 标记结果为负
    }  

    // 重新获取交换后的长度
    lena = strlen(str1);  
    lenb = strlen(str2);  

    // 被减数str1存入数组a(逆序存储,a[1]对应个位)
    for(i = 0; i <= lena - 1; i++)  
        a[lena - i] = str1[i] - '0';  
    // 减数str2存入数组b(逆序存储,b[1]对应个位)
    for(i = 0; i <= lenb - 1; i++)  
        b[lenb - i] = str2[i] - '0';  

    // 高精度减法核心:逐位相减并处理借位
    i = 1;  
    while(i <= lena || i <= lenb)  
    {  
        if(a[i] < b[i])  
        {  
            a[i] += 10; // 借位,当前位加10
            a[i + 1]--; // 高位减1
        }  
        c[i] = a[i] - b[i]; // 对应位相减结果存入c
        i++;  
    }  
    lenc = i;  

    // 删除前导0(保留至少一位,避免全0情况无输出)
    while((c[lenc] == 0) && (lenc > 1))  
        lenc--;  

    // 输出符号(若为负)
    if(is_negative)  
        cout << "-";  

    // 特殊处理:两数相等时,lenc最终为1,c[1]=0,正常输出0
    // 倒序输出结果(从高位到低位)
    for(i = lenc; i >= 1; i--)  
        cout << c[i];  

    cout << endl;  
    return 0;  
}



2.string版本

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int main() {
    string s1, s2;
    cin >> s1 >> s2;
    bool neg = false;

    // 交换处理:确保s1 >= s2
    if (s1.size() < s2.size() || (s1.size() == s2.size() && s1 < s2)) {
        swap(s1, s2);
        neg = true;
    }

    // 逆序处理(方便低位对齐计算)
    reverse(s1.begin(), s1.end());
    reverse(s2.begin(), s2.end());
    
    string res;
    res.resize(s1.size()); //初始化 
    int borrow = 0; // 借位标记

    // 逐位相减
    for (int i = 0; i < s1.size(); i++) {
        int num1 = s1[i] - '0';
        int num2;
        // 判断是否超出s2长度
        if (i < s2.size()) {
            num2 = s2[i] - '0';
        } else {
            num2 = 0;
        }
        
        int sub = num1 - num2 - borrow;
        borrow = 0;
        if (sub < 0) {
            sub += 10;
            borrow = 1;
        }
        res[i] = sub + '0';
    }

    // 第一步:找到第一个非0的最高位(逆序后的末尾方向)
    int len = res.size(); // 有效长度初始化为总长度
    while (len > 1 && res[len - 1] == '0') {
        len--; // 仅修改有效长度标记,不删除字符串内容
    }
    // 恢复正序(仅处理有效长度内的字符)
    reverse(res.begin(), res.begin() + len);
    // 输出结果:仅输出有效长度内的字符(跳过无效的前导0)
    if (neg) cout << "-";
    // 从res的末尾(原有效部分的起始)开始输出,长度为valid_len
    for (int i = res.size() - len; i < res.size(); i++) {
        cout << res[i];
    }
    cout << endl;

    return 0;
}


    扫描二维码推送至手机访问。

    版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

    分享给朋友:

    相关文章

    【题解】光荣的梦想

    【题目描述】Prince对他在这片大陆上维护的秩序感到满意,于是决定启程离开艾泽拉斯。在他动身之前,Prince决定赋予King_Bette最强大的能量以守护世界、保卫这里的平衡与和谐。在那个时代,平...

    【题解】结构体与闰年

    【题目描述】定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。【输入描述】年月日【输出描述】当年第几天【样例输入】2000 12 31【样例输出】366...

    字符串比较

    【题目描述】给出了n(n<=100000)个由数字和字母组成的字符串(长度小于1000),求与给出字符串相同字符串的个数。【输入描述】第一行是一个数n。接下来n行,每行都是一个字符串。接下来一行...

    【题解】幸运儿

    【题目描述】n 个人围成一圈, 并依次编号1~n,从编号为1 的人开始,按顺时针方向每隔一人选出一个,当一圈结束之后,剩下的人重新围成一圈,再次从编号1的人开始,如此循环直到剩下两人,这剩下的两人就是...

    【题解】基因锁

    【题目描述】小X终于意识到需要花大力气减重了,他询问了若干个减重专家后决定采用最适合年轻人的运动减重方案,考虑再三,小X最终选择了打羽毛球的方式,一个原因是小X的小伙伴大都喜欢打羽毛球,其次是打羽毛球...

    【题解】发工资

    【题目描述】财务处的小李最近就在考虑一个问题:如果每个员工的工资额都知道,最少需要准备多少张人民币,才能在给每位员工发工资的时候都不用员工找零呢?这里假设程序猿的工资都是正整数,单位元,人民币一共有1...