Сгенерировать все списки размера n, так что каждый элемент находится между 0 и m (включительно)

Сгенерируйте все списки размером n, чтобы каждый элемент находился в диапазоне от 0 до m (включительно).

Таких списков (m+1)^n.


person Yktula    schedule 21.12.2012    source источник
comment
Какие подходы к этой проблеме вы уже пробовали?   -  person phoog    schedule 22.12.2012
comment
С этим конкретным ограничением это так же просто, как и раньше, тем более что большинство языков имеют восьмеричные числа в своих родных библиотеках.   -  person John Dvorak    schedule 22.12.2012
comment
Я не уверен, что вы действительно ищете. Но, основываясь на том, что вы написали, я не понимаю, почему вы не используете 6 вложенных циклов и все. Я что-то пропустил?   -  person Alexander    schedule 22.12.2012
comment
Что вы пробовали? Это довольно тривиальная проблема. Тем более без ограничений.   -  person Codeguy007    schedule 22.12.2012
comment
Я думал, что да, но не мог понять, как это сделать для более общего случая (в заголовке вопроса).   -  person Yktula    schedule 22.12.2012
comment
Я удалил аналогию с лотерейным номером. Я надеюсь, что не вызвал слишком много путаницы в том, что я спрашиваю, но теперь это должно быть очень ясно.   -  person Yktula    schedule 22.12.2012
comment
Исправление: таких списков (m+1)^n.   -  person Keith Randall    schedule 22.12.2012
comment
@KeithRandall Исправлено, спасибо. :)   -  person Yktula    schedule 22.12.2012


Ответы (2)


Есть два простых способа записать общий случай. Один из них описан в существующем ответе @didierc. Альтернатива - рекурсия.

Например, подумайте о методе, который принимает строку в качестве аргумента:

if(input string is long enough)
  print or store it
else
  iterate over digit range
    recursive call with the digit appended to the string
person Patricia Shanahan    schedule 22.12.2012
comment
Я думаю, мне нравится ваше решение больше, чем мое на самом деле. - person didierc; 22.12.2012

Это похоже на перечисление всех чисел по основанию (m+1) из n цифр.

start with a list of n zeros
do the following loop
    yeld the list as a new answer
    increment the first element, counting in base (m+1), and propagate the carry recursively on its next element
    if there is a carry left, exit the loop

Обновление: просто для удовольствия, какое будет решение, если мы добавим ограничение, согласно которому все цифры должны оставаться разными (например, номер лотереи, как было указано изначально - и, конечно, мы предполагаем, что m >= n)?

Мы продолжаем перечислять все числа с указанным выше ограничением, а также с тем, что любой элемент должен быть больше, чем его преемник в списке (т.е. цифра ранга k < n больше, чем цифра ранга k+1). Это реализуется простой проверкой при вычислении переноса, что текущая цифра не станет равной предшествующей, и, если это так, распространения переноса дальше.

Затем для каждого списка, полученного в результате перечисления, вычислить все возможные перестановки. Существуют известные алгоритмы для выполнения таких вычислений, см., например, Алгоритм Джонсона-Троттера, но можно построить более простой рекурсивный алгоритм:

 function select l r:
   if the list r is empty, yeld l
   else
     for each element x of the list r
        let l' be the list of x and l
        and r' the remaining elements of r
        call select l' r'
person didierc    schedule 21.12.2012