2015-09-06 4 views
-1

Я пытаюсь объединить два списка кортежей, x и y. В принципе, у меня есть эти списки:Алгоритм для объединения двух списков

[("hello", "hi"), ("foo", "baz"), ("this", "that")] 

--and 

[("foo", "bar"), ("hello", "world"), ("goo", "boo")] 

--the result should be 

[("hello", "world"), ("foo", "bar"), ("this", "that")] 

я написал это до сих пор:

merge :: (Eq a) => [(a, b)] -> [(a, b)] -> [(a, b)] 
merge [] _ = [] 
merge _ [] = [] 
merge (x:xs) (y:ys) 
    | fst x == fst y = (fst y, snd y) : merge xs ys 
    | otherwise = (fst x, snd x) : merge xs ys 

Проблема с этим решением является то, что он только сливается, которые тот же индекс. Как я могу эффективно перебирать второй список и объединять его в первый?

+0

Это композиция двух отношений. Похоже, вы основываете код на сортированном слиянии, но это действительно не похоже на слияние. См. ['Lookup'] (https://hackage.haskell.org/package/base-4.8.1.0/docs/Data-List.html#v:lookup). Для большей эффективности конвертируйте свои списки в 'Data.Map', что ближе к тому, что они представляют. – luqui

+0

Не уверен, что я понимаю. FYI im a haskell noob. Почему я должен преобразовывать свои структуры в «Data.Map»? – dopatraman

+4

Можете ли вы объяснить, что вы подразумеваете под «слиянием»? Вы дали небольшой пример, но это будет очень полезно выразить словами. – dfeuer

ответ

1

Прямо сейчас, если пункт otherwise не совпадает, ваш код отбрасывает и x, и y. Он должен попытаться объединить x с остальной частью ys. Некоторые подсказки: [x] - это список, который вы можете передать merge, и если вы можете подумать о способе разделить и преодолеть проблему, вы можете объединить пару списков с помощью ++.

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

+0

Тот факт, что текущий код не является рекурсивным, не является проблемой вообще. Это на самом деле довольно эффективно. Проблема в том, что она не делает то, что должна. Оценка Haskell ленива, а это значит, что вам нужно рассуждать об эффективности немного по-другому. – dfeuer

+0

Я думаю, вы неправильно поняли мой ответ, который касался того, как правильно его решить, или я просто не понял. То, что он написал *, на самом деле является хвостовым рекурсивным; это просто неправильно. Но правильное решение будет связано с делением и победой. Я переведу это предложение до конца, так что это менее сбивает с толку отступление. – Davislor

+0

Или, на самом деле, я могу придумать некоторые другие подходы, которые будут одинаково хорошо работать. – Davislor

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