首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >递归前缀解析器阶乘Java

递归前缀解析器阶乘Java
EN

Stack Overflow用户
提问于 2018-10-12 03:33:27
回答 3查看 231关注 0票数 0

我最近开始在uni中学习java,我们必须做的一项任务是理解递归,并将阶乘函数添加到这个波兰符号代码中。我尝试了各种方法,这是最新的一种:

public class PolishNotation {

    public static void main(String[] args) {
        try (Scanner scanner = new Scanner(System.in)) {
            System.out.println("Please enter the operators");
            System.out.println("for operators +, -, *, and !");
            System.out.println("Leave spaces between all operators and digits");
            System.out.print("expression: ");
            System.out.println("value = " + evaluateEXP(scanner));
        }
    }

    //input contains the expression user has entered
    public static int evaluateEXP(Scanner scanner) {
        //checks if there is another digit after current one
        //allows expression to be looked at from right to left
        if (scanner.hasNextInt())
            return scanner.nextInt();

        //if there is another digit after current one then
        //operands and operators are established
        char operator = scanner.next().charAt(0);
        int operand1 = evaluateEXP(scanner);
        int operand2 = evaluateEXP(scanner);
        return evaluateOP(operator, operand1, operand2);
    }

    //operator has to be one of +, - , * or ! otherwise error is given
    private static int evaluateOP(char operator, int operand1, int operand2) {
        if (operator == '+')
            return operand1 + operand2;
        if (operator == '-')
            return operand1 - operand2;
        if (operator == '*')
            return operand1 * operand2;
        if (operator == '/')
            return operand1 / operand2;
        if (operator == '!')
            //if ! used then uses factorial method
            return factorial(operand1);
        //RunTimeException allows to return an error string in a int "type" method
        throw new RuntimeException("operator not allowed for this language");
    }

    private static int factorial(int n) {
        return n == 1 ? 1 : factorial(n - 1) * n;
    }

}

没有错误,但没有结果出来,所以我猜它卡在一个无限循环上。这段代码的想法是,如果我做了!+3 2,它应该做!5,所以返回120,我不能使用while或for循环。其余的操作数起作用了,只有阶乘不起作用。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-10-12 05:04:06

问题是在evaluateEXP中,你的代码总是需要2个操作数。然而,!只接受一个操作数,所以如果你输入像! 5这样的东西,它将等待更多的输入。

解决方案是检查运算符是一元还是二进制,如果是一元,则只接受一个操作数。以下是几种重构代码以实现这一目标的方法:

1)检查evaluateEXP方法中的运算符,如果第二个操作数是二进制的(在本例中不是!),则只获取第二个操作数:

//input contains the expression user has entered
public static int evaluateEXP(Scanner scanner) {
    //checks if there is another digit after current one
    //allows expression to be looked at from right to left
    if (scanner.hasNextInt())
        return scanner.nextInt();

    //if there is another digit after current one then
    //operands and operators are established
    char operator = scanner.next().charAt(0);
    int operand1 = evaluateEXP(scanner);
    int operand2 = 0;
    //only take second operand if operator is not unary
    if (operator != '!') {
        operand2 = evaluateEXP(scanner);
    }
    return evaluateOP(operator, operand1, operand2);
}

2)将扫描器传递给evaluateOP,让它直接获取操作数:

//input contains the expression user has entered
public static int evaluateEXP(Scanner scanner) {
    //checks if there is another digit after current one
    //allows expression to be looked at from right to left
    if (scanner.hasNextInt())
        return scanner.nextInt();

    //if there is another digit after current one then
    //operands and operators are established
    char operator = scanner.next().charAt(0);
    return evaluateOP(operator, scanner);
}

//operator has to be one of +, - , * or ! otherwise error is given
private static int evaluateOP(char operator, Scanner scanner) {
    if (operator == '+')
        return evaluateEXP(scanner) + evaluateEXP(scanner);
    if (operator == '-')
        return evaluateEXP(scanner) - evaluateEXP(scanner);
    if (operator == '*')
        return evaluateEXP(scanner) * evaluateEXP(scanner);
    if (operator == '/')
        return evaluateEXP(scanner) / evaluateEXP(scanner);
    if (operator == '!')
        //if ! used then uses factorial method
        return factorial(evaluateEXP(scanner));
    //RunTimeException allows to return an error string in a int "type" method
    throw new RuntimeException("operator not allowed for this language");
}

3)在第二个解决方案的基础上,你也可以合并这两种方法,因为它们无论如何都是如此紧密地联系在一起:

//input contains the expression user has entered
public static int evaluateEXP(Scanner scanner) {
    //checks if there is another digit after current one
    //allows expression to be looked at from right to left
    if (scanner.hasNextInt())
        return scanner.nextInt();

    //if there is another digit after current one then
    //operands and operators are established
    char operator = scanner.next().charAt(0);

    if (operator == '+')
        return evaluateEXP(scanner) + evaluateEXP(scanner);
    if (operator == '-')
        return evaluateEXP(scanner) - evaluateEXP(scanner);
    if (operator == '*')
        return evaluateEXP(scanner) * evaluateEXP(scanner);
    if (operator == '/')
        return evaluateEXP(scanner) / evaluateEXP(scanner);
    if (operator == '!')
        //if ! used then uses factorial method
        return factorial(evaluateEXP(scanner));
    //RunTimeException allows to return an error string in a int "type" method
    throw new RuntimeException("operator not allowed for this language");
}
票数 1
EN

Stack Overflow用户

发布于 2018-10-12 03:38:37

public static int factorial(int n) {
    if(n==1){
        return 1;
    }
    // the next line is wrong.  I've removed a set of parentheses to make it more clear 
    int output =  factorial((n-1)*n);
    return output;
}

我强烈建议在你的脑海中运行你的代码。如果我将2传递给你的方法,用递归方式调用factorial()的值是什么?提示:它不是1。

票数 0
EN

Stack Overflow用户

发布于 2018-10-12 03:56:41

public static long fact(int n) {
    return n == 0 ? 1L : n * fact(n - 1);
}

由于17!大于Integer.MAX_VALUE,因此最好使用long作为返回类型

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52767633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档