使用预定义定义创建递归基本数学运算

时间:2016-09-28 17:24:33

标签: java math recursion

我计划在JavaFX中推出一款新游戏' Number-Shape-System'。基本上它是一个小记忆游戏,图片与数字相关联。所以' 2' ='天鹅' 5' ='手(手指)'等等。因此,玩家可以看到练习' Swan + Fingers =?'。

我想要的是遵循规则的所有可能的数学运算:

009259

我准备了一个示例实现,但我不知道如何将其转换为递归功能。

$ sed  's/^\([0-9]\+\)/00000\1/; s/^[0-9]*\([0-9]\{6,\}\)$/\1/' foo
019599
009259
009259
009259
009259
009259
009159
009157
RTSR
RTSR
AWKJ001
AWKJ001
AWKJ001
009159

1 个答案:

答案 0 :(得分:1)

正如您在自己的代码中所看到的,对于" length"中的每次增加,您必须嵌套相同代码的另一个块。使用动态长度值,您无法做到这一点。

因此,您将代码块移动到一个方法中,并传入一个参数,该参数包含多少次" nest",即remainingLength。然后,该方法可以使用递减值remainingLength调用自身,直到达到0。

以下是一个示例,使用enum作为运算符。

public static void generate(int length) {
    if (length <= 0)
        throw new IllegalArgumentException();
    StringBuilder expr = new StringBuilder();
    for (int number = 0; number <= 12; number++) {
        expr.append(number);
        generate(expr, number, length - 1);
        expr.setLength(0);
    }
}
private static void generate(StringBuilder expr, int exprTotal, int remainingLength) {
    if (remainingLength == 0) {
        System.out.println(expr);
        return;
    }
    final int exprLength = expr.length();
    for (int number = 0; number <= 12; number++) {
        if (number != exprTotal) {
            for (Operator oper : Operator.values()) {
                int total = oper.method.applyAsInt(exprTotal, number);
                if (total >= 0 && total <= 12) {
                    expr.append(oper.symbol).append(number)
                        .append("(=").append(total).append(")");
                    generate(expr, total, remainingLength - 1);
                    expr.setLength(exprLength);
                }
            }
        }
    }
}
private enum Operator {
    PLUS    ('+', Math::addExact),
    MINUS   ('-', Math::subtractExact),
    MULTIPLY('*', Math::multiplyExact),
    DIVIDE  ('/', Operator::divide);

    final char symbol;
    final IntBinaryOperator method;
    private Operator(char symbol, IntBinaryOperator method) {
        this.symbol = symbol;
        this.method = method;
    }
    private static int divide(int left, int right) {
        if (right == 0 || left % right != 0)
            return -1/*No exact integer value*/;
        return left / right;
    }
}

请注意,排列的数量会快速增长:

1:            13
2:           253
3:         5,206
4:       113,298
5:     2,583,682
6:    61,064,003
7: 1,480,508,933