Код не останавливается, когда головоломка решается, потому что вы не проверяете, решена ли головоломка после рекурсивного вызова.Таким образом, даже если рекурсивный вызов нашел решение, код продолжает работать даже после нахождения решения, пока не попробует каждую возможность.
Поскольку вы говорите, что у вас работает Java-код, я предлагаю вам сравнить логикуJava-программа против этого кода.Вы, вероятно, обнаружите, что в Java-коде есть такой тест.
Редактировать Из вашего комментария выше я вижу, что вы не найдете такого теста в своем Java-коде.потому что там вы злоупотребляете исключениями для «возврата» из рекурсии, когда найдено решение.Надлежащим способом является, чтобы каждый рекурсивный вызов возвращал истинное значение, если он нашел решение, и false, если он не нашел.И затем каждый шаг должен проверять, был ли его дочерний вызов успешным, и сам возвращать успех, если это так.Как то так:
- (BOOL) solveFieldAtRow: (int) row andCol: (int) col {
if (row > 8) {
// reached the end, so it must have succeeded
return YES;
} else {
while (sudokuField[row][col] != 0) {
if (++col > 8) {
col = 0;
row++;
if (row > 8) {
// reached the end, so it must have succeeded
return YES;
}
}
}
for (int num=1; num<10; num++) {
if ([self checkRow:row forNumber:num] && [self checkCol:col forNumber:num] && [self checkFieldAtRow:row andCol:col forNumber:num]) {
sudokuField[row][col] = num;
[self showFieldInConsole:0];
BOOL result;
if (col < 8) {
result = [self solveFieldAtRow:row andCol:col+1];
} else {
result = [self solveFieldAtRow:row+1 andCol:0];
}
if (result) {
// Our child call succeeded, so we pass that back up
// the stack.
return YES;
}
}
}
sudokuField[row][col] = 0;
// If we get here, we could not find a solution. Return failure
// back up the stack.
return NO;
}
}