Просто для другой перспективы по этому вопросу, поскольку у вас уже есть много ответов.
Это правда, что весь подход к решению рекурсии - это использование стека. Однако, если вы точно знаете, что именно решите, вы можете найти альтернативное решение. Или, может быть, не альтернатива точно - только одна, которая будет более компактной.
В этом случае функция дает двоичное представление параметра для целых чисел больше нуля.
Вы можете захотеть использовать:
public static void foo(int number) {
if (number > 0) {
System.out.print(Integer.toBinaryString(number));
}
}
Но это, конечно, может только заработать очки за дерзость в тесте.
Так вот адаптация пути Java на самом деле делает это:
public static void foo(int number) {
if (number > 0) {
char[] chars = new char[32];
int charPos = 32;
char[] digits = { '0', '1' };
do {
chars[--charPos] = digits[number % 2];
number /= 2;
} while (number > 0);
System.out.print(new String(chars, charPos, 32 - charPos));
}
}
Это, по сути, с использованием стека, но не очень сложный. Стек - это просто массив символов, которые вы начинаете заполнять с конца, и отправляйтесь в начало. Вы можете использовать такой массив вместо коллекции, потому что известно, что int
содержит не более 32 бит. Таким образом, вы никогда не столкнетесь с границами массива. По правде говоря, потому что вы работаете только с положительными числами, это может быть даже 31-символьный массив.
Итак, в каждом случае вы поместите текущую цифру в текущую пустую позицию в массиве и переместите указатель влево. В итоге вы преобразуете все персонажи, которые вы собрали в строку, используя конструктор String
, который, как удобно, может использовать указанную часть массива символов.
Фактические операторы, используемые Java немного отличаются:
do {
chars[charPos--] = digits[number & 1];
number >>>= 1;
} while (number != 0);
потому, что смещение и маскирование являются более эффективными, чем операции дивизия. Если вы используете эту версию, она так же эффективна, как и с использованием Integer.toBinaryString()
.
Рекурсивный метод сохраняет свое состояние в стеке вызовов. В общем случае итерационное решение будет делать что-то в «противоположном» порядке, поэтому, если вам нужно точно преобразовать поведение, используйте свой собственный стек для хранения состояния в цикле и удалите все, когда закончите. – azurefrog
что ожидается выход? – Braj
Самое главное отметить, является ли рекурсивная подпрограмма * * хранить состояние в стеке вызовов. Если да, то вам нужно выяснить, как воспроизвести это состояние в итеративной среде. Это часто означает, что вы должны поддерживать структуру данных, подобную стеку, для хранения состояния. Если состояние не хранится * в стеке вызовов (кроме очевидного состояния, связанного с самим вызовом/возвратом), то замена с помощью итеративной схемы тривиальна. –