【问题标题】:Haskell - Sum of the differences between each element in each matrixHaskell - 每个矩阵中每个元素之间差异的总和
【发布时间】:2017-09-08 16:17:56
【问题描述】:

我对 Haskell(以及一般的函数式编程)非常陌生,我正在尝试编写一个名为 “profileDistance m1 m2”,它将两个矩阵作为参数,需要计算每个矩阵中每个元素之间的差异之和......我可能没有很好地解释。让我来代替它。

矩阵形式为:[[(Char,Int)]] 每个矩阵可能看起来像这样:

m1 = [[('A',1),('A',2)],
      [('B',3),('B',4)],   
      [('C',5),('C',6)]]

m2 = [[('A',7),('A',8)],
      [('B',9),('B',10)],   
      [('C',11),('C',12)]]

(注意:我在此示例中按顺序编写了数字,但它们可以是任意顺序的任何数字。但是,每个矩阵中每一行中的字符将匹配,如示例中所示。)

结果(在上面的例子中)看起来像(伪代码):

result = ((snd m1['A'][0])-(snd m2['A'][0]))+((snd m1['A'][1])-(snd m2['A'][1]))+((snd m1['B'][0])-(snd m2['B'][0]))+((snd m1['B'][1])-(snd m2['B'][1]))+((snd m1['C'][0])-(snd m2['C'][0]))+((snd m1['C'][1])-(snd m2['C'][1]))

这在任何具有 for 循环且无功能的语言中都很容易做到,但我不知道如何在 Haskell 中做到这一点。我有一种感觉,像 mapfoldsum 这样的函数会在这里帮助我(诚然,我不能 100% 确定 fold 的工作原理)。我希望有一个简单的方法可以做到这一点...请帮助。

【问题讨论】:

    标签: loops haskell matrix iterator sum


    【解决方案1】:

    这里有个建议:

    solution m1 m2 = sum $ zipWith diffSnd flatM1 flatM2
      where
        diffSnd t1 t2 = snd t1 - snd t2
        flatM1 = concat m1
        flatM2 = concat m2
    

    我写它是为了更容易理解构建块。 基本思想是使用zipWith 同时迭代我们的两个对列表。这里是它的类型:

    zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    

    这意味着它接受一个类型为a -> b -> c的函数,一个a的列表和一个b的列表,它返回一个c的列表。换句话说,zipWith 以迭代为例,您只需指定要对迭代产生的每个项目做什么,在您的情况下将是一对对(一个来自第一个矩阵,另一个来自第二)。

    传递给zipWith 的函数从每对元素中获取snd 元素,并计算差值。回顾zipWith 签名,您可以推断它将返回一个数字列表。所以我们需要做的最后一件事是使用函数sum 对它们求和。

    还有最后一个问题。实际上,我们没有两个要传递给zipWith! 的对列表,而是两个矩阵。我们需要将它们“展平”在一个列表中,保留元素的顺序。这正是concat 所做的,因此在flatM1flatM2 的定义中调用了该函数。

    我建议您查看我提到的每个函数的实现,以便更好地了解迭代是如何通过递归来表达的。高温

    【讨论】:

    • 谢谢!效果很好。
    • @Schytheron:如果您需要将差作为矩阵,而不仅仅是求和,您还可以使用zipWith (zipWith diffSnd) 之类的东西,而不是使用concat 来展平结构。还有diffSnd = (-) `on` snd 使用来自Data.Functionon
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 2021-06-28
    • 2013-12-01
    • 1970-01-01
    • 2019-03-28
    相关资源
    最近更新 更多