Предположим, вы работаете на языке с массивами переменной длины (например, с A[i]
для всех i
в 1..A.length
) и должны написать подпрограмму, которая принимает n
(n : 1..8
) массивов переменной длины элементов в массиве переменной длины длиной n
и должен вызывать процедуру с любой возможной длиной n
массива элементов, где первый выбирается из первого массива, второй выбирается из второго массива и т. д. вперед.
Если вы хотите, чтобы что-то конкретное визуализировалось, представьте, что ваша программа должна принимать такие данные, как:
[ [ 'top hat', 'bowler', 'derby' ], [ 'bow tie', 'cravat', 'ascot', 'bolo'] ... ['jackboots','galoshes','sneakers','slippers']]
и выполните следующие вызовы процедур (в любом порядке):
try_on ['top hat', 'bow tie', ... 'jackboots']
try_on ['top hat', 'bow tie', ... 'galoshes']
:
try_on ['derby','bolo',...'slippers']
Это иногда называют проблемой китайского меню, и для фиксированной n
можно закодировать довольно просто (например, для n
= 3 в псевдокоде)
procedure register_combination( items : array [1..3] of vararray of An_item)
for each i1 from items[1]
for each i2 from items[2]
for each i3 from items[3]
register( [ii,i2,i3] )
Но что, если n
может варьироваться, давая подпись вроде:
procedure register_combination( items : vararray of vararray of An_item)
Написанный код содержал некрасивую инструкцию case, которую я заменил гораздо более простым решением. Но я не уверен, что это лучший (и, конечно, не единственный) способ реорганизовать это.
Как бы вы это сделали? Умные и удивительные - это хорошо, но понятные и удобные в обслуживании - лучше - я просто прохожу этот код и не хочу, чтобы мне перезвонили. Лаконично, ясно и , умный будет идеальным.
Редактировать: Я опубликую свое решение позже сегодня, после того, как другие смогут ответить.
Тизер: я пытался продать рекурсивное решение, но они не пошли на это, поэтому мне пришлось придерживаться написания фортрана в HLL.
Ответ, который я получил, опубликован ниже.