Почему `--var` и`var-1` работают по-разному?
Я написал код для печати всех допустимых комбинаций скобок из n-пар. Однако, с моей первой попытки, алгоритм выводит все комбинации дважды, то есть. Код был:
public static void solve(char[] string, int open, int closed, int index)
{
if (open < 0 || closed < open) {
return;
}
if (open == 0 && closed == 0) {
System.out.println(string);
}
if (open > 0) {
string[index] = '(';
solve(string, --open, closed, ++index);
}
if (closed > open) {
string[index] = ')';
solve(string, open, --closed, ++index);
}
}
Я трачу значительное количество времени на то, чтобы увидеть, что пошло не так. Я полагал, что код перешел в последнюю, если ветка больше, чем должна. Затем, пробуя разные вещи, я понял, что изменение
solve(string, --open, closed, ++index);
в
solve(string, open-1, closed, ++index);
изменил результат. Это привело к получению java.lang.ArrayIndexOutOfBoundsException
, Наконец, я заменил все операции предварительного увеличения соответствующими арифметическими операциями (например, ++index
в index+1
) и код работает правильно.
Мой вопрос не должен --open
а также open-1
вычислить и отправить в функцию то же значение, что и параметр? Почему код ведет себя по-разному, когда они должны вычислять одно и то же значение?
2 ответа
solve(string, --open, closed, ++index);
на самом деле меняется open
быть на один меньше, чем раньше, что делает следующее использование open
чуть ниже действуйте на значение на 1 меньше, чем передано.
solve(string, open-1, closed, ++index);
... с другой стороны проходит open-1
в метод решения, но не меняется open
, поэтому он используется без изменений, когда используется в последующих операторах.
На самом деле --x
это операция перед декрементом, которая всегда будет такой же, как x=x-1;
т.е. сначала уменьшаем x на 1, а затем присваиваем уменьшенное значение x x.
поэтому значение х определенно изменится, когда мы выполним --x
,
но x-1
это просто операция, которую мы делаем на х, а операция вычитать.
здесь мы присваиваем этот результат какому-то аргументу в методе, который получает этот вызов. но он не переназначается на x автоматически.
так x-1
никогда не бывает равных x=x-1;
и, следовательно, x остается тем же, только получатель получает вычтенное значение.
следовательно
solve(string, --open, closed, ++index);
в приведенном выше заявлении предварительный декремент выполняется open
,
так же, как open=open-1;
и, следовательно, открытое значение изменилось.
но
solve(string, open-1, closed, ++index);
Вышеприведенное утверждение вычитает 1 из open
и передача вычитаемого значения в метод.
это так же, как receiveing_variable_in_method_definition = open-1
но открытый не меняется.