鱼C论坛

 找回密码
 立即注册
查看: 60|回复: 2

c++问题

[复制链接]
发表于 6 天前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目描述
求两个不超过200位的非负整数的和。
输入
有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。
输出
一行,即相加后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。
样例输入
22222222222222222222
33333333333333333333
样例输出
55555555555555555555

哪里有问题?
#include<bits/stdc++.h>
using namespace std;
int main(){
    string n1, n2, he = "";
    int len1, len2, cha, weishu, i, r = 0;
   
    cin >> n1 >> n2;
    len1 = n1.size();
    len2 = n2.size();
    cha = len1 - len2;
    //算最高位数,添加前导0补齐位数
    if (cha > 0){
        for (i=0; i<cha; i++){
            n2 = "0" + n2;
        }
        weishu = len1;
    } else if (cha < 0){
        for (i=0; i<(-cha); i++){
            n1 = "0" + n1;
        }
        weishu = len2;
    }
    //相加
    for (i=0; i<weishu; i++){
            if ((int(n1[weishu-i-1]-'0')+int(n2[weishu-i-1]-'0')) <= 9) {
                    he = he + char((int(n1[weishu-i-1]-'0')+int(n2[weishu-i-1]-'0') + r)+48);
                    r = 0;
                } else {
                        he = he + char((int(n1[weishu-i-1]-'0')+int(n2[weishu-i-1]-'0') + r - 10)+48);
                        r = 1;  //进位
                }
    }
    if (r == 1){
            he = "1" + he;
        }
    //去除前导0
        while((he[weishu] == 0) && (weishu > 1)) weishu--;
        for (i=0; i<weishu; i++) cout << he[i];
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 6 天前 | 显示全部楼层
您的代码未完整贴出,但从目前的代码片段和任务描述中,我可以帮您指出一些可能的问题以及如何改正:

1. **代码不完整:** 您的代码片段在`for (i=0; i`后就中断了,没看到完整的逻辑。不过从题目来看,您的主要任务是用字符串来处理大整数的加法操作。

2. **补齐长度的逻辑:** 您应该要用前导`0`补齐两个数字的长度,这点在代码片段中可以看到您在处理`cha`,但具体实现没有显示出来。

3. **逐位相加:** 字符串中的每一位需要从低到高(从后往前)逐位相加,考虑进位。

4. **输出结果:** 输出结果时需要保证去掉前导`0`,但实际上,算法中累加结果的字符串是构造在正确的顺序,因此前导`0`问题不太会出现。

以下是完整实现代码,基于题目要求写清晰易懂的解决方案:
#include <iostream>
#include <string>
#include <algorithm> // 用于reverse
using namespace std;

int main() {
    string n1, n2, he = ""; // he 是存储结果的字符串
    cin >> n1 >> n2;

    // 确保 n1 是较长的一方
    if (n1.size() < n2.size()) {
        swap(n1, n2);
    }

    // 在 n2 的左边补齐前导 0,使两者长度相等
    while (n2.size() < n1.size()) {
        n2 = "0" + n2;
    }

    int r = 0; // 进位
    // 从最低位(尾部)开始逐位相加
    for (int i = n1.size() - 1; i >= 0; i--) {
        int sum = (n1[i] - '0') + (n2[i] - '0') + r; // 当前位的数字相加加上进位
        r = sum / 10; // 计算新的进位
        he += (sum % 10) + '0'; // 当前位的结果
    }

    // 如果最终有进位需要补充
    if (r > 0) {
        he += r + '0';
    }

    // 由于结果是从低位开始累加的,需要反转字符串
    reverse(he.begin(), he.end());

    cout << he << endl;
    return 0;
}

### **代码解读:**
1. **补齐位数:** `while (n2.size() < n1.size())` 确保较短的数字字符串用前导`0`补齐,使得两者长度相等,方便逐位相加。
2. **逐位相加:** 从末尾开始逐位操作,考虑到当前位的值以及进位`r`。
3. **字符串反转:** 累加结果字符串是从低位开始,因此需要最终反转成正确顺序。
4. **进位处理:** 如果最高位产生了进位,需要额外补充`1`到结果中。

### **样例测试:**
输入:
22222222222222222222
33333333333333333333
输出:
55555555555555555555

如果测试仍然有问题,请再详细描述出现的异常现象,我会继续协助您!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 6 天前 | 显示全部楼层
问题:
前导零处理问题:

在去除前导零时,你尝试通过检查 he[weishu] == 0 来去除前导零。但 he[weishu] == 0 实际上会访问到不合法的数组索引,因为 weishu 是最后一个有效的位置索引。你应该检查 he 中的字符是否是 '0'。
字符串拼接方式:

在累加每一位的结果时,你是从结果的末尾拼接字符,这会导致最终的结果是反的。可以使用 push_back() 或者反转字符串来解决这个问题。
计算长度时的处理:

cha 代表了两个字符串的长度差,然而当两个字符串长度相同的情况下,也应该正确处理位数。
没有初始化 he 的正确值:

当没有进位的情况下,he 需要清空或处理得当,避免出现无效字符。
改正后的代码:
cpp
#include<bits/stdc++.h>
using namespace std;

int main(){
    string n1, n2, he = "";
    int len1, len2, cha, weishu, i, r = 0;
   
    cin >> n1 >> n2;
    len1 = n1.size();
    len2 = n2.size();
    cha = len1 - len2;
   
    // 判断两个数字长度差距,补齐位数
    if (cha > 0){
        for (i = 0; i < cha; i++){
            n2 = "0" + n2;  // 在较短的数字前加0
        }
        weishu = len1;
    } else if (cha < 0){
        for (i = 0; i < (-cha); i++){
            n1 = "0" + n1;  // 在较短的数字前加0
        }
        weishu = len2;
    } else {
        weishu = len1;  // 如果长度相同,直接取长度
    }

    // 从低位到高位相加
    for (i = 0; i < weishu; i++){
        int sum = (n1[weishu - i - 1] - '0') + (n2[weishu - i - 1] - '0') + r;
        if (sum < 10) {
            he = char(sum + '0') + he;
            r = 0;  // 清除进位
        } else {
            he = char(sum - 10 + '0') + he;
            r = 1;  // 产生进位
        }
    }

    // 如果最后还有进位,添加到最前面
    if (r == 1){
        he = "1" + he;
    }

    // 输出结果,去掉多余的前导零
    cout << he << endl;

    return 0;
}
主要改动:
字符串拼接的顺序:

使用 char(sum + '0') + he 来确保结果的顺序正确。
进位处理:

在每次计算后,直接将进位清除或者设置为1,处理方式更加简洁。
前导零去除:

在结果字符串中没有显式去除前导零,因为在加法操作中已经避免了前导零的产生。
测试结果:
输入:
22222222222222222222
33333333333333333333
输出:
55555555555555555555
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-21 18:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表