私はリストのリストを持っています、例えば。、そして私はこのリストからサブリストだけを削除する方法があるのではない((x y z) (y z) (x y))
かと思っていました。はすでに'inside'であるため、サブリストです。この例では、を残します。R5RS Scheme
(y z)
(x y z))
((x y z))
これは私が想像するよりも複雑かもしれませんが、マップまたはフィルターを利用すると思いますが、この方法でリスト全体をどのように「クリーン」にするかはわかりません。
問題は見た目より少し難しいです。私はRacketを使用するので、いくつかの非標準機能が表示される場合がありますが、基本的なR5RS手順に固執している場合は、自分で実装するのはそれほど難しいことではありません(疑問がある場合はドキュメントを参照してください)。また、私は自分のソリューションに関数型プログラミングスタイルを好むので、map
s、filter
s、およびその他の高次の手順があることに注意してください。
まず、リストが任意の位置にある別のリストのサブリストであるかどうかをテストする方法が必要です。私はこの投稿のアイデアを使用して、考えられるすべての連続したサブリストを生成しています。
(define (inits lst)
(let loop ((acc '())
(n (length lst)))
(if (negative? n)
acc
(loop (cons (take lst n) acc) (sub1 n)))))
(define (tails lst)
(let loop ((acc '())
(n (length lst)))
(if (negative? n)
acc
(loop (cons (drop lst n) acc) (sub1 n)))))
(define (contiguous-sublists lst)
(cons '()
(remove* '(())
(append-map inits (tails lst)))))
(define (sublist? l1 l2)
(if (member l1 (contiguous-sublists l2)) #t #f))
実際の手順では、入力リストに重複がないと想定していることに注意してください。
(define (remove-sublists lst)
(filter
(lambda (l1)
(andmap
(lambda (l2)
(not (sublist? l1 l2)))
(remove l1 lst)))
lst))
期待どおりに機能します。
(remove-sublists '((x y z) (y z) (x y)))
=> '((x y z))