Algorithm 帮助计算(四叉树)矩阵的列和的算法?
根据此定义和测试矩阵:Algorithm 帮助计算(四叉树)矩阵的列和的算法?,algorithm,haskell,matrix,quadtree,Algorithm,Haskell,Matrix,Quadtree,根据此定义和测试矩阵: data (Eq a, Show a) => QT a = C a | Q (QT a) (QT a) (QT a) (QT a) deriving (Eq, Show) data (Eq a, Num a, Show a) => Mat a = Mat {nexp :: Int, mat :: QT a} deriving (Eq, Show) -- test matrix, exponent is 2, that is matrix i
data (Eq a, Show a) => QT a = C a | Q (QT a) (QT a) (QT a) (QT a)
deriving (Eq, Show)
data (Eq a, Num a, Show a) => Mat a = Mat {nexp :: Int, mat :: QT a}
deriving (Eq, Show)
-- test matrix, exponent is 2, that is matrix is 4 x 4
test = Mat 2 (Q (C 5) (C 6) (Q (C 1) (C 0) (C 2) (C 1)) (C 3))
| | |
| 5 | 6 |
| | |
-------------
|1 | 0| |
|--|--| 3 |
|2 | 1| |
我正在尝试编写一个函数,它将输出一个列总和的列表,比如:[13,11,18,18]
。基本思想是对每个子四叉树求和:
- 如果四叉树是
,则输出a重复(C C)
乘以值2^(n-1)
。示例:第一个四叉树是C*2^(n-1)
,所以我们重复(c5)
5*2^(2-1)=10次,
2^(n-1)=2次,得到[5,5]
- 否则,给定
,我们使用(qabcdd)
a和c(以及b和d)的colsum
zipWith (+) [[10, 10], [12, 12]] [zipWith (+) [[1], [0]] [[2], [1]], [6, 6]]
因为我从Haskell开始,我觉得我遗漏了一些东西,需要一些关于我可以使用的函数的建议不工作列和定义为:
colsum :: (Eq a, Show a, Num a) => Mat a -> [a]
colsum m = csum (mat m)
where
n = nexp m
csum (C c) = take (2 ^ n) $ repeat (c * 2 ^ n)
csum (Q a b c d) = zipWith (+) [colsum $ submat a, colsum $ submat b]
[colsum $ submat c, colsum $ submat d]
submat q = Mat (n - 1) q
任何想法都是非常好的,非常感谢…… < P> >让我们考虑一下你的代码> CalSuth<代码>:
colsum :: (Eq a, Show a, Num a) => Mat a -> [a]
colsum m = csum (mat m)
where
n = nexp m
csum (C c) = take (2 ^ n) $ repeat (c * 2 ^ n)
csum (Q a b c d) = zipWith (+) [colsum $ submat a, colsum $ submat b]
[colsum $ submat c, colsum $ submat d]
submat q = Mat (n - 1) q
它几乎是正确的,除了定义csum(qabcd)=……的那一行之外
让我们想想类型colsum
返回数字列表<代码>ZipWith(+)按元素对两个列表求和:
ghci> :t zipWith (+)
zipWith (+) :: Num a => [a] -> [a] -> [a]
这意味着您需要将两个数字列表传递给zipWith(+)
。而是创建两个数字列表,如下所示:
[colsum $ submat a, colsum $ submat b]
此表达式的类型是[[a]]
,而不是您需要的[a]
您需要做的是连接两个数字列表以获得单个数字列表(这可能就是您想要做的):
类似地,您将
c
和d
的部分和列表连接起来,然后您的函数应该开始工作。让我们进行更一般的讨论,回到手头的目标
考虑如何将四叉树投影到2n×2n矩阵中。我们可能不需要创建这个投影来计算它的列和,但它是一个有用的概念
- 如果我们的四叉树是一个单元,那么我们就用该单元的值填充整个矩阵
- 否则,如果n≥ 1,我们可以将矩阵分成四个象限,让每个子象限树填充一个象限(即,让每个子象限树填充一个2n-1×2n-1矩阵)
- 请注意,还有一个案例。如果n=0(也就是说,我们有一个1×1的矩阵),并且四叉树不是一个单元,会怎么样?我们需要为这种情况指定一些行为-也许我们只是让其中一个子四叉树填充整个矩阵,或者我们用一些默认值填充矩阵
现在考虑这样的投影的列和。
- 如果我们的四叉树是一个单元,那么2n列和都是2n
乘以存储在该单元格中的值
(提示:查看hoogle上的
和replicate
)genericplicate
- 否则,如果n≥ 1,则每列重叠两个不同的象限。 我们一半的专栏将完全由西部象限决定, 另一半由东象限表示,即特定列的总和 可以定义为该列贡献的总和 从其北半部(即,北象限中该列的列和), 和它的南半部(同样) (提示:我们需要将西方列和附加到东方列和 获取所有列的和,并将北半列和南半列的和合并 获取每列的实际总和)
- 同样,我们还有第三种情况,这里的列和取决于 将四个子四叉树投影到1×1矩阵上。幸运的是,1×1矩阵意味着 只有一列和
干杯,为什么第二列和是21?他们不是18岁吗?@Vitek博士:你说得对,谢谢。想法?看起来你在这里问了很多问题,这些都是家庭作业问题。也许问一个同学会是一个更好的解决办法,因为他们也会有同样的问题?要清楚的是,如果你给他提供了提示,告诉他编译错误的来源以及如何纠正(除了为他重写代码之外),问他引导性问题,或者给他一个有细节要填写的草图,我会投+1。这似乎无助于任何人从中学习。我不确定你对基本情况做了什么。更多的单词,更少的代码?我更新了答案:删除了完整的工作代码,并解释了@Gremo的错误所在。另外,就我个人而言,我总是觉得解释性的例子是更好的学习方法,而模糊的暗示则认为我知道一些我不知道的东西。因此,如果一个人问答案,对我来说,这意味着他想要答案(这里:解决任务的代码,完成h所需的代码)
((colsum $ submat a) ++ (colsum $ submat b))