【问题标题】:Haskell - Calculate complex sum using listsHaskell - 使用列表计算复数
【发布时间】:2019-03-26 19:00:30
【问题描述】:

对于用户s=[x1,x2,...,xk]给定的列表,我需要计算总和

x1 * (x2+x3+...x4)
+ (x1+x2) * (x3+x4+...xk)
+ ...
+ (x1+x2+...+x(k-2)) * (x(k-1) + xk)
+ (x1+x2+...+x(k-1)) * xk

来自函数[Int]->Int

请参阅下图中的数学公式以更好地理解:

https://imgur.com/gallery/Oqgpkcu

只是尝试了很少的事情,例如计算列表的总和减去最后一个元素。 顺便说一句,我必须通过使用列表和非常基本的函数(head、tail、init)来实现所有这些

xsum :: [Int] -> Int
xsum s = sumIntList (init s)

sumIntList :: [Int] -> Int 
sumIntList (h:t) = h + sumIntList t
sumIntList [] = 0

调用函数应该产生的一些结果是:

xsum [4,5,8]
124

xsum [1..100]
341665830

感谢阅读!

【问题讨论】:

  • xsum s = sum (zipWith (*) (map sum (inits s)) (map sum (tails s)))
  • 再次感谢您的意见!正如我上面所说,我无法使用 zipWith 和 map (也是 sum)之类的函数来实现它,因为我只能使用非常基本的函数。但是我看看我能不能用你提供的代码做点什么! :-)
  • 当然,所有这些函数的源代码都是公开的,所以你可以复制粘贴来重新实现你不可用的函数。
  • 您在一篇冗长的帖子中隐藏了您的要求。 :) 我没看到。也许它应该以某种方式强调......?
  • 问题是什么?没有问题。

标签: list haskell


【解决方案1】:

您提供的图片显示 * 而不是 ^。很高兴看到你的一些尝试。一种简单的方法是将函数 splitAt 映射到每个可能的索引上,然后在每对上使用函数 sum 以获得(初始段总和,最终段总和)对,然后对于每一对将其元素相乘,然后总结所有结果产品。编码能走多远?

编辑:为了避免潜在的未来读者滚动浏览所有 cmets,下面给出了一个仅使用 sum 的潜在实现。这是次优的,因为它sums 多次重复相同的子列表,更好的实现可能首先在两个方向上使用scanl 来生成部分和并从那里继续。

xsum (x:xs@(y:ys)) = x * sum xs + xsum ((x+y):ys)
xsum _ = 0

EDIT2:我们正在进行(某种)前行和后行的事情,我喜欢它!

xsum = fst . xsum'
  where xsum' (x:xs@(y:ys)) = (\(acc,s) -> (acc + x * (s-x),s) ) $ xsum' ((x+y):ys)
        xsum' [] = (0,0)
        xsum' [x] = (0,x)

【讨论】:

  • 是的 ^ 是我的错误,正确的符号是 * ,这里是 stackoverflower 的一个同事,感谢上帝。不远,但我会试试。也因为它是一项学校作业,我什至不能使用这些函数 sum ,如果你在我发布的代码中看到我自己创建了一个。
  • 确实,但我提到的几个函数中的每一个都很容易实现,并且从这些简单的块中构建它可能更容易(如果需要,您可以在其中查看前奏实现!)。虽然,也有一个不太复杂的直接递归定义。如果您展示您的尝试,我们可以提供增量提示。
  • 好吧,我试试,如果我完成任何事情,我会发送反馈。我很担心,因为我对这个很陌生,只用了两周的时间在 haskell 的课堂上,他们给我们带来了这些问题。
  • xsum (x:xs@(y:ys)) = _ xsum _ = _ 看看您是否可以在这些定义的右侧填写递归解决方案。您需要的唯一其他功能是您已经(正确)定义的sum。我的提示是我已经对您需要的值进行了模式匹配(即.. 简洁的写作方式提到了所有x, xs, y, ys
  • @A Tayler 我试过 xsum(x:xs@(y:y s)) = x * ( sumIntList xs ) + (x + y) * (sumIntList ys) xsum [2] = 0 xsum [1] = 0 xsum [] = 0 ,但仅适用于第一个。对不起,我无法格式化为代码
猜你喜欢
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2014-10-16
  • 1970-01-01
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
相关资源
最近更新 更多