Использую вложенные циклы как показано в коде ниже для трех и четырех вложенных циклов. PHP: <?php //три вложенных цикла $d=10; for ($i1=0; $i1<$d; $i1++) { for ($i2=0; $i2<$d; $i2++) { for ($i3=0; $i3<$d; $i3++) { $chislo=$i1.$i2.$i3; echo $chislo."<br>"; } } } ?> PHP: <?php //четыре вложенных цикла $d=10; for ($i1=0; $i1<$d; $i1++) { for ($i2=0; $i2<$d; $i2++) { for ($i3=0; $i3<$d; $i3++) { for ($i4=0; $i1<$d; $i4++) { $chislo=$i1.$i2.$i3.$i4; echo $chislo."<br>"; } } } } ?> Чувствую, что в РНР должны быть более изящные решения для такого случая, но из-за незнания так и оставалось. Но теперь встала необходимость в зависимости от поступивших данных (значности числа), задавать количество вложенных циклов от 2 и до 20. Подскажите, каким способом это можно красиво реализовать?
Не надо мне таких решений! Я специально упрошенный код написал, чтобы вам легче было объяснитьа, мне понятней было. А на сам деле, в реальном скрипте, у меня во внутреннем цикле $i_ используется как ключ элемента массива.
блудный сын, ты хочешь чтобы тебе кодом написали как делается рекурсия? О_о Самый яркий пример, который мне показали в глубоком детстве, это функция вычисления факториала Код (Text): <?php function fuck ($num) { if ($num==1) return 1; return ($num*fuck($num-1)); } echo ('10!='.fuck(10)); ?> Вот. А в Вашем случае зависит все от конкретных значений. Но, думаю, там ничего сложного, главное (как нам говорили) обязательно корректно описать условие выхода из рекурсии, иначе зациклишься
Значения указаны: $d=10 $i изменяются от 0 до 10. Покажите как реализовать код моего примера для четырех вложенных циклов в виде рекурсии, а я уже попробую догадаться как сделать число циклов плавающим.
блудный сын, не получается у меня сегодня написать. Устал. Получается с кучей статических переменных и условий. В общем не красиво. Мне кажется, что Ваша задача, имеет другое решение, нежели куча вложенных циклов. Я, конечно, постараюсь, написать функцию, но не сейчас, но очень бы хотелось услышать, что за задача такая
Суть решаемой задачи в генерировании всех вариантов слов заданной длинны из заданных символов. Например от пользователя пришло: длина слова - 4 буквы; используемые символы - "xyz" Теперь, зная, что букв 4 решаю генерацию слов следующим образом: PHP: <?php //четыре вложенных цикла $simvoli="xyz"; $d=strlen($simvoli); for ($i1=0; $i1<$d; $i1++) { for ($i2=0; $i2<$d; $i2++) { for ($i3=0; $i3<$d; $i3++) { for ($i4=0; $i4<$d; $i4++) { $chislo=$simvoli[$i1].$simvoli[$i2].$simvoli[$i3].$simvoli[$i4]; echo $chislo."<br>"; } } } } ?>
блудный сын, в каком виде функция должна вернуть набор буквосочетаний? в виде массива? И ваабще, может быть правильнее было бы проверять, можно ли получить то что ввел пользователь из того набора букв которое есть, а не генерировать все возможные. Это ж страшно подумать про слово из 8 букв длинной в 5 символов
В каком виде и какие проверки это к сути топика отношения не имеет. Это я все сделаю. Мне мой вариант реализации не нравится. Он получается не гибкий в отношении длины слова. А вариантов слов из 5 букв и 8 символов не так уж и много, всего лишь 32768.
PHP: <?php //numberIn10Base число (слово) в 10ной системе исчисления //digitSet набор новых символов //digitNum - длинна нового числа (слова) function getNumInBase($numberIn10Base, $digitSet, $digitNum) { $newBase = strlen($digitSet); $mod = $numberIn10Base; $number = $numberIn10Base; $newNumber = ''; while ($number>=$newBase) { $mod=($number % $newBase); $number = floor($number/$newBase); $newNumber = $digitSet[$mod].$newNumber; } $newNumber = $digitSet[$number].$newNumber; return str_pad($newNumber, $digitNum, $digitSet[0], STR_PAD_LEFT); } //$digitNum - количество символов //$digitSet - набор символов $digitNum=3; $digitSet='опа'; $vsego = pow(strlen($digitSet), $digitNum); for ($i=0; $i<$vsego; $i++) { $slovo = getNumInBase($i, $digitSet, $digitNum); echo $slovo."<br />"; } ?> В общем, если знакомы с системами исчисления, - то поймете как работает. Не знакомы - даже не пытайтесь. А рекурсией было неправильно пробовать. Потому что на любой вложенности необходимо было помнить результат на уровне выше. Для меня это оказалось очень неудобным и красивого решения я так и не нашел. В этом решении вроде все красиво, но мне немного ненравится строчка Код (Text): return str_pad($newNumber, $digitNum, $digitSet[0], STR_PAD_LEFT); но без нее тоже никуда.
[vs], предложите Ваш вариант блудный сын, потратил драгоценное время, и даже благодарности не услышал
Я впал в ступор пытаясь понять твой код Скрипт работает, но для моего понимания тяжеловат. А понять надо. Параллельно пробую все таки рекурсией решить эту задачу. Если получится.
блудный сын, да ничего там сложного сначала находим сколько всего вариантов возможно. Потом представляем себе, что переданная тобой строка "абвгдеж" есть ничто иное как система исчисления "01234567", только непонятная нам (как у хищника). Но нам то все равно какая она и чья. Делаем полный перебор всех возможных вариантов, но не забываем, что перебираем мы в 10-й системе, а перевести надо в систему хищника вот и все. А на счет корректности - могу заверить. Если не давать пустых строк и отрицательных значений все работает стабильно. Да и точно быстрее и менее нагрузочно, чем рекурсии. Но дело твое. Я, лично, рекурсией решить не смог. Может есть решение итеративным методом, но я с ним не знаком
блудный сын, попробуй говорю же - любая система исчисления. Хоть 100-ричная хоть 1-ричная Перевод производится в цикле while, ну и следующая за ним строчка.
Попробовал. Действительно работает хоть для всего алфавита. Для себя добавил комментарии к строчкам твоего кода, застрял на строчке: Код (Text): return str_pad($newNumber, $digitNum, $digitSet[0], STR_PAD_LEFT); Подскажи что в ней происходит? Я с таким сложным ретурном еще не сталкивался.
PHP: str_pad($newNumber, $digitNum, $digitSet[0], STR_PAD_LEFT) Эта функция добавляет к строке нужное количество символов.. просто допустим ситуация: тебе нужны строчки из 5 символов, но, допустим, первое значение будет выглядеть как: х десятое как х0 и пр... необходимо выполнить форматирование строки, а именно дополнить слева ведущими нулями. В нашем случае, нули - это символ с индексом [0] в переданной строке символов системы исчисления. Вот и получается, что мы возвращаем строку $newNumber, дополненную до длинны $digitNum символами $digitSet[0] слева STR_PAD_LEFT. Вот надеюсь понятно. Можешь сделать просто return $newNumber и посмотришь что произойдет. Тогда сразу поймешь что происходит.
Понятненько. А смотри что у меня получается: PHP: <?php //$n - номер цикла //$max - максимальное число циклов (оно равно длине слова) //$letters - используемые для перебора буквы //$stroka - получившаяся и передаваемая дальше строка function cicle($n,$max,$letters,$stroka) { for ($i[$n]=0; $i[$n]<$max; $i[$n]++) { $stroka=$stroka.$letters[$i[$n]]; if ($n+1<$max) { $n=$n+1; cicle($n,$max,$letters,$stroka); } else { for ($ii=0; $ii<$max; $ii++) { echo $stroka.$letters[$ii]."<br>"; } } $stroka=''; } return; } cicle (0,4,"abcd",''); ?>
Не знаком потому не пытаюсь )) А с рекурсией чтобы помнить резултат - можно специальный для этого аргумент к функции добавить. Получилось как у блудный сын, менее красиво... ;-)