Привязка странного поведения в рекурсии цикла - PullRequest
1 голос
/ 02 декабря 2011

Я изучаю Clojure и пытаюсь решить проблему 31 : написать функцию, которая упаковывает последовательные дубликаты в подсписки.

(= (__ [1 1 2 1 1 1 3 3]) '((1 1) (2) (1 1 1) (3 3)))

Я знаю, что могу решить это, используя идентичность, и функционально, но я хочу решить это, используя рекурсию, потому что я не до конца внедрил эту идею в своем мозгу.

Мое решение будет таким:

(defn packing [lista]
  (loop [[fst snd :as all] lista    mem []    tmp '(fst)]

   (print "all is   "    all   "\n\n") ;; something is wrong; it always is an empty list

   (if (seq? all)
     (if (= fst snd)
         (recur (rest all) mem (cons snd tmp))
         (recur (rest all) (conj mem tmp) (list snd)))
    (seq mem))))

Моя идея - рекурсивный цикл, всегда берущий первые 2 элемента и сравнивающий. Если они совпадают, я включаю их во временный список tmp; если они разные, я включаю свой временный список в men. (Это мой окончательный список; лучшее имя будет final_list.)

Поскольку он сравнивает первые 2 элемента, но в то же время ему нужен рекурсивный цикл только в обход первого элемента, я назвал весь список all.

Я не знаю, хороша ли логика, но все же, если это не так, я не знаю почему, когда я печатаю.

 (print "all is   "    all   "\n\n") I receive an empty list

Ответы [ 2 ]

1 голос
/ 02 декабря 2011

Несколько точек:

  • '(fst) создает список, содержащий символ fst, а не значение fst, это одна из причин, по которой следует использовать векторы, например,[fst]
  • вам следует избегать предположения, что ввод не будет пустым
  • вы можете использовать conj как для списков, так и для векторов
  • деструктуризация является нестабильной
(defn packing [coll]
    (loop [[x & [y :as more] :as all] coll
           result                     []
           same                      '()]
    (if all
     (if (= x y)
       (recur more result (conj same x))
       (recur more (conj result (conj same x)) '()))
     result)))
0 голосов
/ 05 декабря 2011

в вашем коде все не пусто ... случается только бесконечный цикл, и вы всегда видите пустой список ... в первых строках вы можете увидеть, чем он работает, как ожидалось ..

ошибка в (seq? All), потому что пустой список тоже seq ... попробуй (seq? '()) И верни true ... тогда ты делаешь пустой цикл вам нужно изменить это для (пусто? все) ваш код будет другая ошибка - '(fst), потому что она возвращает символ fst, а не значение ... измените его на (список fst)

(defn badpacking [lista]
  (loop [[fst snd :as all] lista    mem []    tmp (list fst)]
    (if (empty? all)
       (seq mem)
       (if (= fst snd)
           (recur (rest all) mem (cons snd tmp))
           (recur (rest all) (conj mem tmp) (list snd))))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...