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

如何修改仅支持单数字的递归Java计算器以适配多数字运算?

Fixing Your Recursive Java Calculator for Multi-Digit Numbers

Hey there! The main reason your calculator only handles single-digit numbers is that your factor() method reads just one digit and calls it a day. Let's fix that—we'll adjust the method to read consecutive digits and combine them into a full number, while keeping your existing recursive structure for operator precedence intact.

Key Modification: Update the factor() Method

Right now, factor() checks for a single digit, converts it, and moves on. To support multi-digit numbers, we need to:

  • When we encounter a digit, keep reading subsequent characters as long as they're digits.
  • Combine these digits into a single integer (e.g., '1' followed by '2' becomes 12).

Modified Code

Here's the updated version of your calculator with multi-digit support. I've highlighted the critical changes and included the required ParseError class for completeness:

import java.io.IOException;
import java.io.InputStream;

public class Calculator {
    private int lookAheadToken;
    private InputStream inputStream;

    public Calculator(InputStream inputStream) throws IOException, ParseError {
        this.inputStream = inputStream;
        lookAheadToken = inputStream.read();
    }

    private void consume(int symbol) throws IOException, ParseError {
        if (lookAheadToken != symbol)
            throw new ParseError();
        lookAheadToken = inputStream.read();
    }

    private int evalDigit(int digit) {
        return digit - '0';
    }

    private void goal() throws ParseError, IOException {
        int result = expr();
        if (lookAheadToken == '\n') {
            System.out.println("result = " + result);
        }
        consume(lookAheadToken);
        if (lookAheadToken == -1)
            return;
        goal();
    }

    private int expr() throws ParseError, IOException {
        int result = term();
        return rest_expr(result);
    }

    private int rest_expr(int factor) throws ParseError, IOException {
        if (lookAheadToken == '\n' || lookAheadToken == ')' || lookAheadToken == -1)
            return factor;
        if (lookAheadToken != '+' && lookAheadToken != '-')
            throw new ParseError();
        char operator = (char) lookAheadToken;
        consume(lookAheadToken);
        int result = term();
        if (operator == '+') {
            return rest_expr(factor + result);
        } else if (operator == '-') {
            return rest_expr(factor - result);
        } else
            return factor;
    }

    private int term() throws ParseError, IOException {
        int result = factor();
        return rest_term(result);
    }

    private int rest_term(int factor) throws ParseError, IOException {
        if (lookAheadToken == '\n' || lookAheadToken == ')' || lookAheadToken == -1)
            return factor;
        if (lookAheadToken == '+' || lookAheadToken == '-')
            return factor;
        if (lookAheadToken != '*' && lookAheadToken != '/')
            throw new ParseError();
        char operator = (char) lookAheadToken;
        consume(lookAheadToken);
        int result = factor();
        if (operator == '*') {
            return rest_term(factor * result);
        } else if (operator == '/') {
            return rest_term(factor / result);
        }
        return factor;
    }

    // Updated to handle multi-digit numbers
    private int factor() throws ParseError, IOException {
        if (lookAheadToken == '(') {
            consume(lookAheadToken);
            int result = expr();
            if (lookAheadToken == ')') {
                consume(lookAheadToken);
                return result;
            } else
                throw new ParseError();
        }
        if (lookAheadToken < '0' || lookAheadToken > '9')
            throw new ParseError();
        
        // Build the full multi-digit number
        int number = 0;
        while (lookAheadToken >= '0' && lookAheadToken <= '9') {
            number = number * 10 + evalDigit(lookAheadToken);
            consume(lookAheadToken);
        }
        return number;
    }

    public static void main(String[] args) throws IOException, ParseError {
        InputStream inputStream = System.in;
        Calculator calculator = new Calculator(inputStream);
        calculator.goal();
    }
}

// Required ParseError exception class
class ParseError extends Exception {
    public ParseError() {
        super("Invalid expression syntax");
    }
}

What Changed?

  • Revised factor(): Instead of reading one digit, we initialize a number variable to 0. We then loop as long as the next token is a digit:
    • Multiply the current number by 10 (to shift existing digits left, e.g., 1 becomes 10 when we read a '2')
    • Add the value of the new digit
    • Consume the digit token and repeat until we hit a non-digit character
  • Added ParseError class: Included it since your original code noted it's required for error handling.

Testing It Out

Try these test cases to verify the fix:

  • 123+45 → Outputs result = 168
  • 9*87-6 → Outputs result = 777
  • (10+20)*3 → Outputs result = 90

This preserves your original recursive logic for operator precedence and parentheses, while adding full support for multi-digit numbers.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:02:58