challenge ファイル内の重複行削除(後優先)

アレイのuniq」の応用編です。

入力されたテキストデータから重複する行をとりのぞいて、その結果を標準出力へ出力するプログラムを作成してください。

重複行の排除については、以下の仕様を満たしてください。

  1. 読み込み順序は変更しないこと
  2. 重複する行があった場合、以前のデータを削除すること (後に読み込んだ方が強い)
  3. ファイル全体を一度にメモリに読み込んで処理しないこと
  4. 比較は行全体で行うこと

#4.はおまけですがある/なしで作りが変わってくると思われるので追加しました。


この問題はraynstardさんにご投稿いただきました。ご協力ありがとうございます。 ところで、素朴な実装のしかたをするとメモリ容量の数倍のサイズのすべての行が異なっているファイルを読ませたときに大変なことが起こりそうな気がしますが、そういうシビアなお題設定ではないので素朴に解いてしまって構いません。シビアなのは続編にしたいと思います。

Posted feedbacks - Haskell

ナイーブ。文字エンコードはUTF8。とりあえず、
標準入力 → 標準出力
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
module Main where

import Control.Applicative
import qualified Data.Set as S
import qualified System.IO.UTF8 as U

main :: IO ()
main = mapM_ (U.putStrLn . snd)
     . S.toAscList . S.map pair
     . foldl ((S.insert <*>) . flip S.delete) S.empty
     . zipWith N [1..] . lines =<< U.getContents
  where pair (N i s) = (i,s)

data NL = N Int String
instance Eq NL where
  N _ s == N _ s' = s == s'
instance Ord NL where
  N _ s `compare` N _ s' = s `compare` s'


	
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import System (getArgs)
import System.IO
import System.IO.UTF8 as U
import Data.List ((\\))
import Control.Exception (bracket)

main = do
  (file:_) <- getArgs
  bracket (openFile file ReadMode) hClose exec

exec :: Handle -> IO ()
exec = loop []
  where loop ret h = do
          eof <- hIsEOF h
          if eof then U.print ret
                 else U.hGetLine h >>= return . (\l -> (ret \\ [l]) ++ [l]) >>= flip loop h

Index

Feed

Other

Link

Pathtraq

loading...