2016-10-11 9 views
-2

lispでペアを機能させようとしています。ペア関数は2つの入力を取得し、ペアを作り、1つのリストを作成します。ここに私のコードです。lispで入れ子になったループを使ってペアを作る方法

(defun npair (s1 s2) 
    (let ((result '())) 
    (cond ((null s1) s2) 
      ((null s2) s1) 
      (t (loop 
       (when (null s1) (return result)) 
       (while (not (null s2)) 
       (setq result (cons (list (car s1) (car s2)) result)) 
       (setq s2 (cdr s2))) 
       (setq s1 (cdr s1))))))) 

この関数は、(npair '(a b c) '(1 2))のように戻ってきたはずです - >((a 1) (a 2) (b 1) (b 2) (c 1) (c 2))

しかし、私の結果は唯一((a 1) (a 2))です。 助けてください!

+0

WHILEが不明なため、コードを実行できません。 –

+0

あなたのヌルケースの条件は、これが正しいデカルト積ではないことを意味します。いずれかのリストが空の場合、結果は空でなければなりません。空でないリストのすべての要素と空のリストのすべての要素の組み合わせが空であるためです。もちろん、私たちは好きな関数を定義することができます。特別な事例*を無償で出力すると、有用な価値を持つことはまずありません。 – Kaz

答えて

3

あなたは外側のループでは、内側のループからの値(複数可)を蓄積したい場合、あなたは、単に値を積算ではなく変数を変異させることによって、それをやろうとしているオフおそらく方がよいでしょう:

(loop for e1 in p1 
    append (loop for e2 in p2 
      collect (list e1 e2))) 

あなたの書式設定もオフになっています、カスタムは新しい行に終端のカッコを入れないことです。上からのループ構造を使用して

、あなたの全体の機能は、このように次のようになります。

、ニース、シンプルで非常に読みやすい
(defun npair (p1 p2) 
    (loop for e1 in p1 
     append (loop for e2 in p2 
       collect (list e1 e2)))) 

0

見た目では、あなたが望む結果はデカルト製品と呼ばれます。私はSchemeプログラミング言語で使用

実装はこのように書きます。たとえば

(define (product . args)                
    (if (null? args)                 
     (list '())                  
     (apply append                 
       (map (lambda (rest)              
        (map (lambda (first)            
          (cons first rest))          
          (car args)))            
        (apply product (cdr args)))))) 

ここシェスキームを使用して出力されます。

> (product '(a b c) '(1 2)) 
((a 1) (b 1) (c 1) (a 2) (b 2) (c 2)) 
1

他の人があなたをより良い代替案を示したが実装よりも望ましい結果を得るには、実装がうまくいかない理由を次に示します。s2の値をnullに変更し、最初の要素を残りの要素であるs1を処理する前に元の値s2を復元しないでください。 (これは複数の理由の一つである理由あなたが最初の場所でそれらを変異させずに入力値をループする必要があります。)ここで

が、それはその入力突然変異していないため、実際にどのような作品あなたの実装のバージョンです:

(defun npair (s1 s2) 
    (let ((result '())) 
    (cond ((null s1) s2) 
      ((null s2) s1) 
      (t (loop for e1 in s1 
       do (loop for e2 in s2 
         do (push (list e1 e2) result))) 
      (nreverse result))))) 
関連する問題