如何从元组列表构建指定大小的二维矩阵?(Haskell实现)
解决Haskell的buildMatrix函数实现问题
首先,你当前的代码有个小问题:函数参数写的是(i, j, v),这只能接受单个元组,但题目要求的是处理元组列表[(Int, Int, Int)]。我们需要调整逻辑来支持多个位置的赋值,同时默认填充0。
这里是完整的实现,结合你的思路修改:
import Data.Maybe (fromMaybe) buildMatrix :: Int -> [(Int, Int, Int)] -> [[Int]] buildMatrix n entries = let -- 把元组列表转换成以(row, column)为键、value为值的关联列表 keyedEntries = [ ((r, c), v) | (r, c, v) <- entries ] -- 定义单个位置的取值逻辑:找到对应键就取value,否则返回0 entry row col = fromMaybe 0 (lookup (row, col) keyedEntries) in -- 生成n行,每行有n个元素,每个元素调用entry计算 [ [ entry row col | col <- [1..n] ] | row <- [1..n] ]
代码解释:
- 导入
fromMaybe:这个函数来自Data.Maybe模块,用来处理lookup返回的Maybe Int——如果找到值就返回它,找不到就用默认值0。 - 转换元组列表:
keyedEntries把每个(r,c,v)元组转换成((r,c), v),这样我们可以用lookup通过(row,col)快速查找对应的值。 - entry函数:对于每个1-based的
row和col,查找是否有对应的赋值,没有就返回0。 - 生成矩阵:用列表推导式生成n行,每行包含n个元素,每个元素由
entry row col计算得到。
测试示例:
当你调用buildMatrix 3 [(1,2,1), (1,3,-1), (2,3,1)]时,会得到:
[[0,1,-1],[0,0,1],[0,0,0]]
和题目要求的输出完全一致。
额外优化(可选):
如果担心重复查找影响效率(比如n很大或者元组列表很长),可以把关联列表转换成Map,这样查找时间从O(k)(k是元组数量)变成O(log k):
import Data.Map (Map) import qualified Data.Map as Map buildMatrix :: Int -> [(Int, Int, Int)] -> [[Int]] buildMatrix n entries = let entryMap = Map.fromList [ ((r, c), v) | (r, c, v) <- entries ] entry row col = Map.findWithDefault 0 (row, col) entryMap in [ [ entry row col | col <- [1..n] ] | row <- [1..n] ]
这个版本在处理大量元组时性能更好,但对于小规模场景,第一个版本已经足够简洁好用。
内容的提问来源于stack exchange,提问作者WhiteW
相关产品推荐
相关产品推荐

