English 中文(简体)
数据关系复杂合并
原标题:Complex merge of data relations

请允许我指出,我有一套关系,似乎这样:

relations :: [(A, B)]
instance Monoid A
instance Monoid B

我想将这套关系转变为一套新的<代码>关系。 A和。 B

现在,这里的trick脚:是:

  1. As that are equal should have their Bs mappended.
  2. Bs that are equal should have their As mappended.
  3. Repeat until all As and Bs are distinct (Or don t, depending on if this can be done non-iteratively somehow).

www.un.org/Depts/DGACM/index_spanish.htm EDIT: 令状的制约使问题变得微不足道,因此我删除了这个问题。

可以假定,<代码>Ord,Hashable,或您需要的任何其他东西。 就所有意图和目的而言,人们可以说,A>s behaves exactly<>em> /em>,如HashSet B behavesexactly,如Vector(或其他一些具有合理规模检查的类型)。

This means that one can assume that let s = size (mappend a b); s >= size a; s >= size b, and that a, b :: B; mappend a b /= mappend b a <=> a, b not mempty; a > b => (mappend a c) > b, etc.

An example of how this transformation would happen (Pretend that <a, b> is Set.fromList [a, b])

[(<1>, [a]), (<4>, [d]), (<2>, [b]), (<5>, [e]), (<1>, [b]), (<2>, [a]), (<3>, [c])]
-- Merge `A`s for equal `B`s
[(<1,2>, [a]), (<4>, [d]), (<1,2> [b]), (<5>, [e]), (<3>, [c])]
-- Merge `B`s for equal `A`s
[(<1,2>, [a, b]), (<4>, [d]), (<5>, [e]), (<3>, [c])]
-- All values are distinct, so we re done.

如何以尽可能高效率的方式(时间、空间)做到这一点?

最佳回答

我认为,不能比奥(n^2)合并的直截了当的方法做得更好,因此,总算法可以是奥(n^3)。 在不限制名单上各项内容的次序和<编码>>>>>>>>> 空白/代码”结果的情况下,你必须匹配每个要素,看它们是否应当合并,然后重复。

merge :: Eq e => (a -> a -> a) -> (a -> e) -> [a] -> (Bool,[a])
merge combine eqval [] = (False, [])
merge combine eqval (x:xs) = (not (null a) || t, y : zs)
  where
    e = eqval x
    (a,b) = partition ((e ==) . eqval) xs
    y = mconcat (x:a)
    (t,zs) = merge combine eqval b

mergeRelations :: [(A,B)] -> [(A,B)]
mergeRelations = go False
  where
    mergeFsts = merge ((a1,b1) (a2,b2) -> (a1, b1 `mappend` b2)) fst
    mergeSnds = merge ((a1,b1) (a2,b2) -> (a1 `mappend` a2, b1)) snd
    go started xs
      | started && not f = xs
      | s = go True n
      | otherwise = m
        where
          (f,m) = mergeFsts xs
          (s,n) = mergeSnds m
问题回答

暂无回答




相关问题
Euler Problem in Haskell -- Can Someone Spot My Error

I m trying my hand at Euler Problem 4 in Haskell. It asks for that largest palindrome formed by multiplying two three-digit numbers. The problem was simple enough, and I thought my Haskell-fu was up ...

How does foldr work?

Can anybody explain how does foldr work? Take these examples: Prelude> foldr (-) 54 [10, 11] 53 Prelude> foldr (x y -> (x+y)/2) 54 [12, 4, 10, 6] 12.0 I am confused about these executions....

Efficient queue in Haskell

How can I efficiently implement a list data structure where I can have 2 views to the head and end of the list, that always point to a head a tail of a list without expensive calls to reverse. i.e: ...

Problem detecting cyclic numbers in Haskell

I am doing problem 61 at project Euler and came up with the following code (to test the case they give): p3 n = n*(n+1) `div` 2 p4 n = n*n p5 n = n*(3*n -1) `div` 2 p6 n = n*(2*n -1) p7 n = n*(5*n -3)...

Ways to get the middle of a list in Haskell?

I ve just started learning about Functional Programming, using Haskel. I m slowly getting through Erik Meijer s lectures on Channel 9 (I ve watched the first 4 so far) and in the 4th video Erik ...

haskell grouping problem

group :: Ord a => [(a, [b])] -> [(a, [b])] I want to look up all pairs that have the same fst, and merge them, by appending all the list of bs together where they have the same a and discarding ...

Closest equivalent to subprocess.communicate in Haskell

I want to do a popen() / python s subprocess.communicate from Haskell - start a program, give it stdin, and get its stdout/stderr. What s the most direct / Haskellish way to do this?