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

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

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

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

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

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


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

Posted feedbacks - Scheme

ひさしぶりの投稿。
1
2
3
4
5
6
7
8
(use srfi-1)
(use srfi-42)
(define (uniq-file file)
  (call-with-input-file file
    (lambda (p)
      (let1 ls (fold-ec '() (:port ln p read-line)
                        ln (lambda (x r) (append (delete! x r) (list x))))
        (do-ec (: ln ls) (print ln))))))

冒頭のarglみたいな手続き欲しいです。
1
2
3
4
5
6
7
8
(define (argl proc) (lambda arg (proc arg)))

(let ((h (make-hash-table 'string=?))
      (c 0))
  (port-for-each (cut hash-table-put! h <> (inc! c)) read-line)
  (for-each (compose print car)
            (sort (hash-table-map h cons)
                  (compose (apply$ <) (argl (map$ cdr))))))

port-fold がありました。
1
2
3
4
5
(use srfi-1)
(define (uniq-file file)
  (define (rp ls) (unless (null? ls) (rp (cdr ls)) (print (car ls))))
  (with-input-from-file file
    (lambda () (rp (delete-duplicates (port-fold cons '() read-line))))))

Index

Feed

Other

Link

Pathtraq

loading...