1

この質問は以前に尋ねられたことを知っています。私の解決策は多くの回答と同じですが、この問題の一般的な解決策では正しく機能しない特別なテスト ケースがあります。

他の多くの場合と同様に、zipの問題に対して私が見つけた解決策は

(define (zip l1 l2)(map list l1 l2))

. . .これは、次のような特定の引数でうまく機能します

(zip '(a b c) '(1 2 3)) => ((a 1) (b 2) (c 3))

しかし、引数が次のように長さと一致しない場合でも、zip関数が機能するようにしたい

(zip '(a b c) '(1)) => ((a 1) (b ()) (c ()))

私はこの問題の解決策を見つけていません。また、各リストが任意の長さにできる場合にアプローチする方法がよくわかりません。

4

2 に答える 2

0

(zip '(a b c) '(1))=>を持つことは意味的に正しくありません((a 1) (b ()) (c ()))(特に()プレースホルダー値として使用している場合を除きます)。持っている方が賢明((a 1) (b) (c))です。これを実現する実装は次のとおりです。

(define (zip-with-uneven . lists)
  (define (advance lst)
    (if (null? lst)
        lst
        (cdr lst)))
  (define (firsts lists)
    (let loop ((lists lists)
               (result '()))
      (cond ((null? lists) (reverse result))
            ((null? (car lists)) (loop (cdr lists) result))
            (else (loop (cdr lists) (cons (caar lists) result))))))

  (let loop ((lists lists)
             (results '()))
    (if (andmap null? lists)
        (reverse results)
        (loop (map advance lists)
              (cons (firsts lists) results)))))

andmapラケットからです。Racket を使用していない場合は、every代わりに SRFI 1 から使用できます。


本当にプレースホルダーを使用したい場合は、プレースホルダーをサポートする (Racket 固有の) バージョンがあります。デフォルトのプレースホルダーは です(void)。これは、結果リストに入れたい有効な値ではないと思います。

(define (zip-with-uneven #:placeholder (ph (void)) . lists)
  (define (advance lst)
    (if (null? lst)
        lst
        (cdr lst)))
  (define (cons-with-placeholder a d)
    (if (void? a)
        d
        (cons a d)))
  (define (firsts lists)
    (let loop ((lists lists)
               (result '()))
      (cond ((null? lists) (reverse result))
            ((null? (car lists))
             (loop (cdr lists) (cons-with-placeholder ph result)))
            (else (loop (cdr lists) (cons (caar lists) result))))))

  (let loop ((lists lists)
             (results '()))
    (if (andmap null? lists)
        (reverse results)
        (loop (map advance lists)
              (cons (firsts lists) results)))))
于 2013-06-23T02:39:09.833 に答える