Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 移除具有Int列表的列表中的元素(Haskell)_List_Haskell - Fatal编程技术网

List 移除具有Int列表的列表中的元素(Haskell)

List 移除具有Int列表的列表中的元素(Haskell),list,haskell,List,Haskell,我正在编写一个函数,它获取一个Int列表,一个常规类型的a列表,并删除Int列表中具有索引的所有元素 例如:removeEl[1,3,4][1,2,3,4,5,6]return[1,3,6] 或者removeEl[1,2]“Firefox”return“Fefox” 以下是我的尝试: removeEl :: [Int] -> [a] -> [a] removeEl [] xs = [] removeEl ns [] = [] removeEl (n:ns) (x:xs) | n ==

我正在编写一个函数,它获取一个
Int
列表,一个常规类型的
a
列表,并删除Int列表中具有索引的所有元素

例如:
removeEl[1,3,4][1,2,3,4,5,6]
return
[1,3,6]
或者
removeEl[1,2]“Firefox”
return
“Fefox”

以下是我的尝试:

removeEl :: [Int] -> [a] -> [a]
removeEl [] xs = []
removeEl ns [] = []
removeEl (n:ns) (x:xs) | n == 0 = removeEl ns xs
                       | n > 0 = x:removeEl (n-1) xs

我意识到
(n-1)
Int
,而不是
[Int]
,所以它失败了。我是否需要编写一个辅助函数来使用?

您需要传递一个新列表,但该列表中的每一项都需要递减,因为您已经移动了第二个参数中每个元素的位置。无论您是否实际删除了head元素,这都是正确的

removeEl (n:ns) (x:xs) | n == 0 = removeEl (map pred ns) xs
                       | n > 0 = x:removeEl (map pred (n:ns)) xs
有很多机会重构它,但我玩过的任何东西都感觉不到更简单

此外,您的第一个基本情况是错误的:由于索引列表中没有项目,您希望返回所有内容,而不是什么都不返回:

(请记住,只有当第一个参数是单调递增的时,这才有效。)


您还可以通过列表理解避免显式递归:

removeEl ns xs = [x | (n,x) <- zip [0..] xs, not(n `elem` ns)]

removeEl ns xs=[x |(n,x)我相信你的算法是
O(n*m)
,其中
n
是列表中的元素数,
m
是要删除的索引数。它还有一个不幸的要求,索引列表必须有序。这里有一个
~O(n*log(m))
不需要订购索引的解决方案

import qualified Data.Set as Set

removeE1 indices xs = go 0 xs
  where is = Set.fromList indices
        go _ [] = []
        go n (y:ys) | n `Set.member` is = go (n+1) ys
                    | otherwise         = y : go (n+1) ys

n>0
的情况下,您还需要减少以下索引(不仅仅是第一个)。我试过编写代码,但它说
没有(Num(Int->Int)的实例在map
的第一个参数中,错误在case
n==0
的第行,因为我仍然忘记了负文本在Haskell中是一件痛苦的事情。我们也可以使用
pred
来简化它,而不是
减去1
啊,我忘记了
pred
import qualified Data.Set as Set

removeE1 indices xs = go 0 xs
  where is = Set.fromList indices
        go _ [] = []
        go n (y:ys) | n `Set.member` is = go (n+1) ys
                    | otherwise         = y : go (n+1) ys