1

リストを取り込む関数を作成しようとしていますが、要素の1つが負の場合、そのリスト内の正の要素と等しい要素はすべて0に変更する必要があります。たとえば、-2がある場合リスト内の場合、そのリスト内のすべての2を0に変更する必要があります。

なぜそれが特定の場合にのみ機能し、他の場合には機能しないのか、何か考えはありますか?これがなぜなのかわかりません。何度か調べました。

changeToZero [] = []
changeToZero [x] = [x]
changeToZero (x:zs:y:ws) | (x < 0) && ((-1)*(x) == y) = x : zs : 0 : changeToZero ws
changeToZero (x:xs) = x : changeToZero xs

changeToZero [-1,1,-2,2,-3,3]
-- [-1,1,-2,2,-3,3]

changeToZero [-2,1,2,3]
-- [-2,1,0,3]

changeToZero [-2,1,2,3,2]
-- [-2,1,0,3,2]

changeToZero [1,-2,2,2,1]
-- [1,-2,2,0,1]
4

3 に答える 3

7

リスト内包表記は、ここでより明確で簡単に理解できると思います。

changeToZero xs = [if x > 0 && (-x) `elem` xs then 0 else x | x <- xs]

より効率的なものが必要な場合は、を使用する代わりに、一連の負の要素を作成して確認できelemます。

import qualified Data.Set as Set

changeToZero' xs = [if (-x) `Set.member` unwanted then 0 else x | x <- xs]
  where unwanted = Set.fromList $ filter (< 0) xs
于 2012-10-06T21:50:54.753 に答える
2

リストで見つけた負の記号を実際には覚えていません

import qualified Data.Set as S

changeToZero :: [Int] -> [Int]
changeToZero [] = []
changeToZero xs = reverse . snd $ foldl f (S.empty,[]) xs
  where
    f (negs,res) x | x < 0 = (S.insert (-x) negs, x:res)
                   | S.member x negs = (negs,0:res)
                   | otherwise = (negs,x:res)
于 2012-10-06T21:51:07.693 に答える
2

@jdevelopからの回答に基づいて、カウントするためにネガティブがポジティブの前に表示される必要がある場合は、入力を逆にすることなく、入力を1回パスするだけで結果を作成できます。

import qualified Data.Set as S
import Control.Monad.State

changeToZero :: [Int] -> [Int]
changeToZero xs = evalState (mapM f xs) S.empty where
  f x | x < 0     = modify (S.insert (-x)) >> return x
      | otherwise = gets (S.member x) >>= \hasNeg -> return $ if hasNeg then 0 else x

このようにして、あなたは答えを得ることができます

take 4 $ changeToZero $ 1 : (-2) : 3 : 2 : undefined

他のソリューションが失敗する場所。

** 編集 **

これは同じことですが、Stateモナドがないため、理解しやすくなっています。

changeToZero' :: [Int] -> [Int]
changeToZero' = go S.empty where
  go _ [] = []
  go s (x:xs) | x < 0        = x : go (S.insert (-x) s) xs
              | S.member x s = 0 : go s xs
              | otherwise    = x : go s xs
于 2012-10-07T18:50:56.033 に答える