我的问题是转这个:
iSort :: Ord a => [a] -> [a]
iSort [] = []
iSort (x:xs) = ins x (iSort xs)
ins x [] = [x]
ins x (y:ys)
| x <= y = x : y : ys
| otherwise = y : ins x ys
进入一个跟踪比较次数的解决方案,这里是我需要生成的代码框架:
iSortCount :: Ord a => [a] -> (Integer, [a])
iSortCount [] = ...
iSortCount (x:xs) = ...
insCount x (k, []) = ...
insCount x (k, (y:ys)) -- Count the times when it reach's here
| x <= y = ...
| otherwise = ...
where ...
我已经尝试了很多东西,从使用lets,wheres,writer monad,制作我自己的类型,state monad,我似乎只是在看一些东西,因为我一直遇到“y:ins x ys”的问题因为该函数返回的应该是 (Int, [a]) 并且 : 不适用于元组。我试图把它分开来做这样的事情
do
(a,b) <- ins x (k+1, ys)
return (k, (y : b))
但它似乎不认为 ins 在那个版本中返回一个元组,所以我猜它只是不是模式匹配。我的主要问题是我现在应该看哪里?我为此工作了很长时间,这个问题开始让我感到沮丧,因为它看起来很容易......
在以斯拉的帮助下回答:
iSort' [] = []
iSort' (x:xs) = ins' x (iSort' xs)
ins' x [] = [x]
ins' (x,i) (y:ys)
| x <= fst y = (x,i+1) : y : ys
| otherwise = y : ins' (x,i+1) ys
countInsertions x = sum $ map snd $ iSort' $ zip x $ repeat 0