2014-01-17 34 views
0

假設我有一個從220的所有整數列表。當n適合謂詞時,移除位置n和n-1中的元素。

[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 

我也有一個功能f x返回要麼TrueFalse。當我將此函數應用於位置n上的元素並且它等於True時,我想要移除它和其先前元素(位置爲n-1處的元素)。我想繼續這樣做直到列表中的元素的功能等於True以及它們的前面元素爲空。

例如: 假設位於11的元素(等於13)符合謂詞。然後我想刪除位置10上的元素,也就是12。在那之後我的最終名單將是:

[2,3,4,5,6,7,8,9,10,11,14,15,16,17,18,19,20] 

讓我們也說,在位置48以及15的元素是符合謂詞的唯一元素(除了在13位置的元素)。消除他們和他們前面的元素後,我最終的名單將是這樣的:

[2,3,4,7,8,11,14,15,18,19,20] 

我是一個沒有經驗的程序員的Haskell,只是玩耍的樂趣。我想過使用某種lambda函數作爲過濾器的謂詞,或者創建一個像listRemove xs ys這樣的函數,它刪除xs的所有元素,它們也是ys的元素,但我覺得兩者都有些失落。

任何幫助,將不勝感激!

編輯:我試圖做的是解決Project Euler問題,即#179。謂詞f x用於檢查x是否爲質數。因此,我可以肯定地說沒有角落案例存在 - 例如沒有例如[x, x, t, t]其中t是一個謂詞成立的數字,因爲除了23之外不存在兩個連續的整數,我可以在我的解決方案中輕鬆處理這兩個整數。相反,最接近你可以得到的是[x, t, x, t],在這種情況下,我想刪除所有這些元素。

+0

我不確定自從[上一個類似問題](http://stackoverflow.com/q/21182206/3015232)以來發生了什麼變化。你似乎有一些目的,但你不與我們分享 - 也許你可以解釋最初的問題,因爲可能有一個直接解決這個問題的優雅方法。請閱讀[XY問題](http://meta.stackexchange.com/a/66378/242387)。 –

+0

從表面上看,你可以稍微重複一下你之前提出的問題的答案,但是對前一個問題的編輯介紹了這個問題,其中包含了比這更多的想法。你提到了替換或編輯值。如果你想用20 * 5替換19和20,因爲20滿足你的謂詞,你是否想要對照謂詞檢查新的100?你是否嘗試過回答你的舊問題的代碼? –

+0

您的刪除操作沒有很好的定義,您必須指定一個訂單。怎麼樣的角落情況(x,x,t,t),其中't'是謂詞成立的元素?因爲(x,x,t,t) - >(x,t) - >()[我們移除內部(x,t)]或(x,x)[我們移除(t ,T)]? – Zeta

回答

1

解決「的位置處刪除元素n和n-1的一個Haskell列表中,當n嵌合的謂詞」

filter' :: (a -> Bool) -> [a] -> [a] 
filter' f xs = map (\i -> xs!!i) $ 
       [i | i <- [0 .. s], fit i && (i >= s || fit (i+1))] 
       where s = length xs - 1 
        fit i = not (f (xs!!i)) 

用法

*Main> filter' (==4) [1,2,3,4,5,6] 
[1,2,5,6] 

*Main> filter' (\n -> n `mod` 7 == 0) [1..23] 
[1,2,3,4,5,8,9,10,11,12,15,16,17,18,19,22,23] 

*Main> filter' (\n -> n `elem` [4,5,6]) [1..10] 
[1,2,7,8,9,10] 

隨着爲O(n )費用可能是

filter' :: (a -> Bool) -> [a] -> ([a], Bool) 
filter' _ [] = ([], False) 
filter' f [x] = if f x then ([], True) else ([x], False) 
filter' f (y:xs) = case filter' f xs of 
        (xs', True) -> (xs', f y) 
        (xs', False) -> if f y then (xs', True) else (y:xs', False) 

使用STANDAR功能

filter' f xs = filter (not.f) $ map fst $ filter (not.f.snd) $ zip xs $ tail xs ++ [last xs] 
1

假設你有:

filterWithTails :: ([a] -> Bool) -> [a] -> [a] 
filterWithTails f = map head . filter f . filter (not . null) . tails 

filterWithTails (not . any disallowed . take 2) [2..20] 

disallowed :: Int -> bool 
-- A function that matches your example 
disallowed x = elem x [6, 10, 13, 17] 

你想要什麼,如果你想給它一個名字僅僅是

import Data.List (tails) 

map head . filter (not . any disallowed . take 2) . filter (not . null) . tails $ [2..20] 

(not . any disallowed . take 2)是如何在過濾時考慮列表的其餘部分來過濾列表。要想給出一個更好的名字比構成它的功能的組成更難。