Реализация рекурсии в Java
просто для ясности, это не домашнее задание, Я изучаю CS в свое время!
вставьте математический оператор ( + , -,÷, x) в каждое из пространств для решения уравнения:
6 _ 3 _ 5 _ 7 _ 4 _ 8 = 13
насколько я понимаю, для решения этой проблемы с помощью рекурсии мне сначала нужно определить базовый случай. Однако у меня проблемы с этим.
Итак, мой вопрос в том, что такое возможный базовый случай и как я должен начать его реализовывать? Как может выглядеть рекурсивная функция (аргументы, тип возврата и т. д.)? (код полезен, пожалуйста)!
это то, что у меня есть до сих пор:почти работает я думай!--2-->
см. мой ответ для реализации
N. b. Я использую Java
4 ответов
Я думаю, что условие остановки должно означать, что уравнение выполнено: все операторы заполнены, а операции приводят к правильному равенству.
Я бы выразил уравнение как дерево разбора, с листьями как числами и родителями как операторами. Дерево, естественно, поддается рекурсии, потому что это иерархическая структура данных.
сделать предположение оператора, где корневая операция является знаком минус, правильный ребенок является желаемым значение (13), а левый дочерний элемент-левая сторона. Добавьте оператор, оцените дерево и вернитесь назад, пока не будет выполнено условие остановки.
базовый случай, когда все пробелы заполняются операторами. Вы можете решить эту проблему, используя поиск по глубине:
algorithm dfs(i):
if i == num_blanks: # base case: filled in all the blanks
if equation_solved():
return the operators you filled in
else:
for op in (+, -, ÷, ×):
blank[i] = op
if dfs(i + 1) returns a solution:
return that solution
blank[i] = _ # restore to previous state
это рекурсивный способ поиска по всему комбинаторному пространству. (Надеюсь, это не испортит вам упражнение; я написал его в псевдокоде, чтобы оставить реализацию вам.)
вы можете думать об этом как о дереве решений.
6
/ / \ \
+ - * /
3 Assuming you choose + for the first operator
/ / \ \
+ - * /
5 5 5 5
^ ^
6 + 3 - 5 6 + 3 / 5
затем вы можете использовать алгоритм обхода графика, такой как DFS или BFS, чтобы проверить результат. Оба они рекурсивны.
вот реализация, с которой я закончил, но сначала объяснение решения проблемы:
- базовый вариант (как сказал larsmans и Ян Дворжак) - это когда все "_" заполняются операторы (такие как "+").
- функция вызывает себя, добавляя каждый раз другой параметр, пока он не достигнет неверного базового случая (например "6+3+5+7+4-8=13") или у него есть правильный ответ.
- если базовый случай неверен, то мы продолжаем появляться уровни мы получаем на уровень с оператором, который мы можем изменить.
вот код:
class GapFill {
private static String numbers; //E.g. 6_5_4=15
private static String[] blank; //Array of operators to go in the blanks
//Where:
//p = plus
//m = minus
//d = divide
//t = times
private static String[] operators = {"p", "m", "d,", "t"};
public static void main(String[] args) {
numbers = args[0];
blank = new String[numbers.split("_").length - 1];
if(dfs(0)) { //If a solution was found
int count = 0;
while(numbers.indexOf("_")!=-1) {
int index = numbers.indexOf("_");
numbers = numbers.substring(0,index)+blank[count]+numbers.substring(index+1);
count++;
}
System.out.println(numbers);
}
}
private static boolean dfs(int i) {
if(i == blank.length) { //base case: filled in all the blanks
return solveEquation();
}
for(String op : operators) {
blank[i] = op;
if(dfs(i + 1)) {
return true;
}
}
blank[i] = "_"; //restore to previous state
return false;
}
private static boolean solveEquation() {
String[] eachNumber = numbers.substring(0, numbers.indexOf("=")).split("_");
String finalResult = numbers.substring(numbers.indexOf("=")+1, numbers.length());
double currentResult = Double.parseDouble(eachNumber[0]);
for(int i=1;i<eachNumber.length;i++) {
String op = blank[i-1];
if(op==operators[0]) {
currentResult = currentResult + Integer.parseInt(eachNumber[i]);
} else if(op==operators[1]) {
currentResult = currentResult - Integer.parseInt(eachNumber[i]);
} else if(op==operators[2]) {
currentResult = currentResult / Integer.parseInt(eachNumber[i]);
} else if(op==operators[3]) {
currentResult = currentResult * Integer.parseInt(eachNumber[i]);
}
}
return (currentResult==Integer.parseInt(finalResult));
}
}
вывод java GapFill 6_3_5_7_4_8=13
is 6m3p5m7p4p8=13
.
символы "p,m,d,t" используются вместо"+, -,÷,×", так как терминал не любит × или ÷