【问题标题】:Algorithm to check quadtree horizontal symmetry?检查四叉树水平对称性的算法?
【发布时间】:2011-02-05 15:45:07
【问题描述】:
data (Eq a, Show a) => QT a = C a | Q (QT a) (QT a) (QT a) (QT a)
    deriving (Eq, Show)

根据上述定义,编写一个谓词来检查给定图像(编码为四叉树)是否关于垂直轴对称(水平对称)。尽可能使用匿名函数。

问题您将如何对给定的四叉树实施水平对称检查?

嗯,我在想这样的事情:当四叉树只是一个叶子时,在这种情况下,我们有水平对称性。基本情况是当四叉树只有一级(四叶)对称性时,只需检查颜色(c1 == c2 && c3 == c4)

在任何其他情况下,我可能会检查此条件是否满足递归:nw equals (fliphorizontal(ne)) && sw equals (fliphorizontal(se)),其中fliphorizontal 水平翻转四叉树,equals 检查两个四叉树是否相等。但是,我想尽可能避免使用外部函数,如果可能的话,只使用匿名函数。

ishsymmetric :: (Eq a, Show a) => QT a -> Bool
ishsymmetric (C _)                           = True
ishsymmetric (Q (C c1) (C c2) (C c3) (C c4)) = c1 == c2 && c3 == c4
ishsymmetric (Q nw ne sw se)                 =

编辑:翻转示例:

fliph :: (Eq a, Show a) => QT a -> QT a
fliph (C a)           = C a
fliph (Q nw ne sw se) = Q (fliph ne) (fliph nw) (fliph se) (fliph sw)

编辑:最终的单函数解决方案(使用四叉树的广义折叠函数):

ishsymmetric :: (Eq a, Show a) => QT a -> Bool
ishsymmetric (C _)       = True
ishsymmetric (Q a b c d) = and $ zipWith equals [a,c] [fliph b,fliph d]
    where
        fold f g (C c)       = g c
        fold f g (Q a b c d) = f (fold f g a) (fold f g b)
                                 (fold f g c) (fold f g d)
        fliph q = fold (\a b c d -> Q b a d c) (\c -> C c) q
        equals (C c1) (C c2)           = c1 == c2
        equals (Q a b c d) (Q e f g h) = and $ zipWith equals [a,b,c,d] [e,f,g,h]

【问题讨论】:

  • @Yasir Arsanukaev:已修复,谢谢。
  • 编辑了第一篇文章...
  • 您可以收集并报告您作为 cmets 的改进,然后稍后编辑问题,使其包含 cmets。如果您将问题编辑 8 次,它就会成为社区 Wiki。 CW 不会生成代表。所以不要经常编辑你的帖子。
  • 我不确定,但也许 where 语法会满足您的需求 :-) freebsd.pastebin.com/QX1Bi0sj
  • @Yasir Arsanukaev:很好的起点,谢谢。

标签: algorithm haskell functional-programming quadtree


【解决方案1】:

类似:

ishsymmetric :: (Eq a, Show a) => QT a -> Bool
ishsymmetric (C _)                           = True
ishsymmetric (Q (C c1) (C c2) (C c3) (C c4)) = c1 == c2 && c3 == c4
ishsymmetric (Q nw ne sw se) = equals nw (fliph ne) && equals sw (fliph se)
    where equals (C a) (C b) = a == b
          equals (Q a b c d) (Q e f g h) = equals a e && equals b f && equals c g && equals d h
          fliph (C a)           = C a
          fliph (Q nw ne sw se) = Q (fliph ne) (fliph nw) (fliph se) (fliph sw)

但句法优化是可能的。 :-/

【讨论】:

  • 或者:equals (Q a b c d) (Q e f g h) = and$zipWith equals [a,b,c,d] [e,f,g,h] (freebsd.pastebin.com/DgMW4Txh)。
  • @Yasir Arsanukaev: and$ 和做的一样吗: foldr (&&) True (zipWith equals [a, b, c, d] [e, f, g, h])?
  • @Gremo:是的。您可以在 GHCi 中使用 :t all:t foldr (&&) True 来检查函数签名。它们是相同的。此外,您可以使用foldl1,它是foldl 的变体,没有起始值参数。顺便说一句,我已经在你之前的问题“Too many pattern matches to write down for Quadtrees?”中指出了all。 :-) 等等,$ 是一个应用操作符,定义在Prelude,见Application operator
  • @Yasir Arsanukaev:我喜欢 zipWith 解决方案,它非常简洁优雅。我假设and 不像&& 那样短路,对吧?
  • @Gremo: 嗯,zipWith 允许你任意态射(确保结果是一个列表),而andfoldl1 (&&) 的简写,它产生一个Bool 值列表。该死,我为什么混淆alland? :-)
【解决方案2】:

怎么样

ishsymmetric qt = qt == fliph qt

【讨论】:

  • 你的意思是ishsymmetric qt = equals qt (fliph qt)
  • @Gremo 我很确定equals 方法是不必要的......因为QT 已经派生Eq
猜你喜欢
  • 2014-01-17
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多