繁体   English   中英

使用Int(Haskell)列表删除列表中的元素

[英]Remove elements in list with a list of Int (Haskell)

我正在编写函数,该函数接受一个Int列表,一个通用类型a列表并删除在Int列表中具有索引的所有元素。

例如: removeEl [1,3,4] [1,2,3,4,5,6]返回[1,3,6]removeEl [1,2] "Firefox"返回"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

有很多机会可以重构它,但是我玩过的任何东西都感觉不那么简单。

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

remove [] xs = xs

(请记住,这仅在第一个参数单调增加时有效。)


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

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

我相信您的算法是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

而且,可以通过使用哈希映射来改善这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM