簡體   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