2014-02-02 2 views
0

say У меня есть список в haskell [2,4,6,8,9,4], и я хочу начать с первого элемента, а затем перепрыгнуть на один или два элемента и получить все возможные комбинации .so я должен получить список списков. поэтому для приведенного выше списка я хочу вернуть следующий список [[2,6,9], [2,6,4], [2,8,4]]. я написал до сих порСписок списков Haskell

paths :: [int] -> [int] 
paths [] = [] 
paths [x]=[x] 
paths (x:z:xs) = x:paths(xs) 

но возвращает только один список, начиная с первого элемента, а затем прыгать на них. Поэтому я не знаю, как заставить его рекурсировать так, чтобы он перескакивал два и все для всех возможных прыжков.

Помощь приветствуется.

+1

Обратите внимание, что 'int' соответствует любому типу (что хорошо в данном случае), так как она начинается со строчной буквы , Основной тип целочисленного размера слова - 'Int'. Все, что содержится в сигнатуре типа, начинающейся с строчной буквы, является переменной типа. –

+0

Вы можете начать с функции, которая фактически возвращает список списков. Тип должен быть '[a] -> [[a]]'. –

+0

Является ли '[2,8]' частью вывода для этого ввода? Если это не так, почему бы и нет? – Carl

ответ

2

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

Но в первую очередь, позволяет фиксировать тип:

paths :: [a] -> [[a]] 

Кроме того, я собираюсь изменить базовый вариант: если вход пуст, результат не пустой список, но вместо список, содержащий пустой список, поскольку на пустом множестве есть только одна комбинация, и это снова пустое. Кроме того, для одноточечного, мы будем возвращать упакованный одноплодный список:

paths [] = [[]] 
paths [x] = [[x]] 

А что, если у нас есть несколько элементов? Сначала мы помним, прыгаем через один или два, а затем снова применяем paths. Однако мы прыгаем только два, если есть что-то, что можно перепрыгнуть. Затем мы помещаем первый элемент обратно на фронт:

paths (x:xs) 
| null jump1 = [[x]] 
| otherwise = map (x:) $ paths jump1 ++ paths jump2 
where jump1 = drop 1 xs 
     jump2 = drop 2 xs 

Пример:

 
\> paths [2,4,6,8,9,4] 
[[2,6,9],[2,6,4],[2,8,4],[2,8]] 
+0

Это именно то, что я искал, вы aa life saver Zeta, спасибо soooo much :) –

+0

Я настоятельно рекомендую против записывая эту функцию, используя 'length'. Это заставляет его работать значительно медленнее. Кроме того, с некоторой незначительной настройкой алгоритм может быть выполнен для работы с бесконечными списками, если он не использует 'length'. – Carl

+0

Для любознательных, эта небольшая настройка является заменой '++' чередованием двух результатов подтаблицы. – Carl

Смежные вопросы