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

【题解】大整数减法

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

【题目描述】

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

【输入】

共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;
}


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

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

分享给朋友:

相关文章

【题解】最大数问题

【题目描述】输入若干个整数。输出其中的最大数【输入描述】若干个整数。【输出描述】其中的最大数。【样例输入】1 2 5 7 8 6 1&nbs...

【题解】营救巨轮

【题目描述】一艘远洋巨轮在大海中遇到故障,船长库克立刻发出了求救信号。距离最近的辽宁号收到了讯息,时间就是生命,必须尽快赶到那里。通过侦测,辽宁号获取了一张海洋图。这张图将海洋部分分化成n*n个比较小...

【题解】阳光

【题目描述】给出一个n*n的矩阵,矩阵每个元素数值代表这个位置的阳光情况,给出正整数k,需要我们求出哪一处的k*k 区域的阳光平均值最多,阳光平均值为k*k 区域的阳光总和除于k*k。蒜头君想让我们输...

【题解】开关灯(1)

【题目描述】假设有N盏灯(N为不大于5000的正整数),从1到N按顺序依次编号,初始时全部处于开启状态;有M个人(M为不大于N的正整数)也从1到M依次编号。第一个人(1号)将灯全部关闭,第二个人(2号...

八皇后2

【题目描述】会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 × 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。对于某个满足要求的8...

【题解】增添战斗力

【题目描述】大战即将来临,杰洛特需要为自己增添战斗力,广袤的大陆有诸多豪杰,正好可以为杰洛特所用    杰洛特分别有两处地方n1,n2需要豪杰的战斗力    一...