You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RPN计算器异常求助:多位数运算结果仅显示最后一位

问题分析与修复方案

你遇到的核心问题是代码没有处理多位数的情况——不管是中缀转后缀还是后缀计算环节,都把每个数字字符当成了单独的操作数,导致多位数被拆成单个数字计算,最终结果完全偏离预期。比如输入13时,代码会把它当成1和3两个独立的数,而不是整数13。

具体问题点

  1. 中缀转后缀阶段:遇到数字字符时直接逐个写入后缀字符串,没有将连续的数字组合成完整的数,也没有添加分隔符区分不同操作数/运算符。比如1+1生成的后缀是11+,而13生成的后缀是13,两者无法区分是两个单数字还是一个多位数。
  2. 后缀计算阶段:逐个字符处理后缀字符串,每个数字字符单独转成整数入栈,导致多位数被拆分成多个单数字计算,完全不符合预期逻辑。

修复步骤

1. 修改中缀转后缀函数,支持多位数并添加分隔符

修改infix_to_postfix方法,处理连续数字并在每个token(操作数/运算符)后添加空格分隔,这样后续计算时能清晰区分每个元素:

void infix2postfix :: infix_to_postfix() {
    int i,p=0;
    char next;
    char symbol;
    int len = strlen(infix);
    for(i=0; i<len; i++) {
        symbol=infix[i];
        if(!white_space(symbol)) {
            switch(symbol) {
                case '(': 
                    push(symbol); 
                    break;
                case ')': 
                    while((next=pop())!='(') {
                        postfix[p++] = next;
                        postfix[p++] = ' '; // 运算符后加空格分隔
                    }
                    break;
                case '+': case '-': case '*': case '/': case '%': case '^': 
                    while( !isEmpty() && priority(stack[top])>= priority(symbol) ) {
                        postfix[p++]=pop();
                        postfix[p++] = ' '; // 弹出的运算符后加空格分隔
                    }
                    push(symbol);
                    break;
                default: /*处理多位数操作数*/
                    // 读取所有连续的数字字符
                    while(i < len && isdigit(infix[i])) {
                        postfix[p++] = infix[i];
                        i++;
                    }
                    i--; // 外层循环会自动i++,这里回退一步避免跳过字符
                    postfix[p++] = ' '; // 操作数后加空格分隔
                    break;
            }
        }
    }
    while(!isEmpty()) {
        postfix[p++]=pop();
        postfix[p++] = ' '; // 剩余运算符后加空格分隔
    }
    // 去掉最后多余的空格,添加字符串结束符
    if(p > 0) p--;
    postfix[p]='\0';
}

2. 修改后缀计算函数,按分隔的token处理

修改eval_post方法,按空格分割后缀字符串的每个token,区分数字和运算符,正确处理多位数:

int infix2postfix :: eval_post() {
    int a,b,temp,result;
    char token[20]; // 存储单个token,支持最大19位数字
    int token_idx = 0;
    int len = strlen(postfix);
    
    for(int i=0; i<=len; i++) {
        // 遇到空格或字符串结束时,处理当前token
        if(postfix[i] == ' ' || postfix[i] == '\0') {
            if(token_idx == 0) continue; // 跳过空token(比如连续空格)
            
            token[token_idx] = '\0';
            token_idx = 0;
            
            if(isdigit(token[0])) {
                // 数字token转成整数入栈
                int num = atoi(token);
                push(num);
            } else {
                // 运算符token,弹出两个数计算
                a=pop();
                b=pop();
                switch(token[0]) {
                    case '+': temp=b+a; break;
                    case '-': temp=b-a; break;
                    case '*': temp=b*a; break;
                    case '/': temp=b/a; break;
                    case '%': temp=b%a; break;
                    case '^': temp=pow(b,a); break;
                    default: 
                        cout << "Unknown operator: " << token[0] << endl;
                        exit(1);
                }
                push(temp);
            }
        } else {
            // 收集当前token的字符
            token[token_idx++] = postfix[i];
            if(token_idx >= 20) {
                cout << "Error: Too long number" << endl;
                exit(1);
            }
        }
    }
    result=pop();
    return result;
}

3. 替换不安全的gets函数

原代码中gets(infix)存在缓冲区溢出风险,建议换成更安全的fgets:

int main() {
    infix2postfix ip;
    top=-1;
    cout<<"Enter infix : ";
    // 使用fgets读取输入,避免缓冲区溢出
    fgets(infix, sizeof(infix), stdin);
    // 去掉输入末尾的换行符
    infix[strcspn(infix, "\n")] = '\0';
    
    ip.infix_to_postfix();
    cout<<"Postfix : "<<postfix<<endl;
    cout<<"Result is : "<<ip.eval_post()<<endl;
    return 0;
}

测试验证

修复后测试你的例子:

  • 输入中缀: (1+1)*13+10/2
    后缀: 1 1 + 13 * 10 2 / +
    结果为: 31
  • 输入中缀: 2*13+10/2
    后缀: 2 13 * 10 2 / +
    结果为: 31
  • 输入中缀: 3*2+5
    后缀: 3 2 * 5 +
    结果为: 11

所有案例都能得到正确结果。

内容的提问来源于stack exchange,提问作者Victoria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:09:26