我正在尝试在Haskell中执行多项式计算器,并且我在乘法方面遇到了一些问题。多项式被引入作为系数列表,其中第一项对应于x ^ 0,第二项对应于x ^ 1,依此类推。
对于乘法,我有一个元组列表,在第一个元素上表示它们所属的系数,在第二个元素上,它们表示相应的系数:
[(0,0),(0,-1),(0,-2),(0,-3),(0,-4),(0,1),(1,0),(2,-1),(3,-2),(4,-3),(0,2),(2,1),(4,0)
(这样做是为了保持对每个项目的乘积和它所属的系数的参考)
由于这是我进入函数式编程的第一步,我在制作一个列表时遇到了一些麻烦,其中第一个元素是上面列表中元组的所有第二个元素的总和,其中0为第一个元素,第二个术语应该是上面列表中元组的所有第二个元素的总和,其中1是第一个元素,依此类推。
我尝试使用第一个回答here中指出的Data.Sequence更新,但似乎并没有“更新”已经创建的Data.Sequence,它每次都返回一个新的。
有没有办法创建列表并根据索引更新其内容?我想知道如何递归地解决这个问题,但我不知道如何做到这一点,所以任何帮助将不胜感激。
答案 0 :(得分:6)
这是解决方案,
import Data.List
import Data.Function
combine :: [(Int,Int)] -> [Int]
combine = map (sum . map snd) . groupBy ((==) `on` fst) . sort
从右到左阅读功能,了解它的作用。
这是破碎成较小的部分以理解它
*Main> sort [(0,0),(0,-1),(0,-2),(0,-3),(0,-4),(0,1),(1,0),(2,-1),(3,-2),(4,-3),(0,2),(2,1),(4,0)]
[(0,-4),(0,-3),(0,-2),(0,-1),(0,0),(0,1),(0,2),(1,0),(2,-1),(2,1),(3,-2),(4,-3),(4,0)]
这会对列表进行排序,因此具有相同第一个元素的所有对都在一起。在此之后,您还可以使用fold
。
*Main> groupBy ((==) `on` fst) . sort $ [(0,0),(0,-1),(0,-2),(0,-3),(0,-4),(0,1),(1,0),(2,-1),(3,-2),(4,-3),(0,2),(2,1),(4,0)]
[[(0,-4),(0,-3),(0,-2),(0,-1),(0,0),(0,1),(0,2)],[(1,0)],[(2,-1),(2,1)],[(3,-2)],[(4,-3),(4,0)]]
这将所有对具有相同的第一元素。
*Main> combine [(0,0),(0,-1),(0,-2),(0,-3),(0,-4),(0,1),(1,0),(2,-1),(3,-2),(4,-3),(0,2),(2,1),(4,0)]
[-7,0,0,-2,-3]
现在我们只需要计算列表列表中第二个元素的总和。