1

リストと合計を取るプログラムを作成しています。リスト内の数値の一部が合計になる場合は、true を返します。それ以外の場合は、false を返します。一部のケースでは機能しているようですが、他のケースでは機能していないようです。例えば、

これを入力すると:

(numlist-sum '(5 9) 9)

数値の 1 つ (9) が合計 (9) に等しいため、true を返す必要があります。しかし、何らかの理由で、false が返されます。

何が問題なのかわかりません。助けてください?

(define (numlist-sum? ls sum)
  (if (null? ls) #t
    (if (and (null? (cdr ls)) (equal? (car ls) sum)) #t
      (if (equal? (car ls) sum) #t
          (if (equal? (cdr ls) sum) #t
              (if (equal? (apply + (car ls) (cdr ls)) sum) #t
                  #f))))))
4

2 に答える 2

0

この問題を解決するためのヒントをいくつかあげます (宿題のようです)。最初に、リストのすべての可能な部分集合 (たとえば、リストのベキ集合) を生成する手続きを書きます。例えば:

(powerset '(1 2 3))
=> '(() (1) (2) (3) (1 2) (1 3) (2 3) (1 2 3))

上記の手順が手元にあれば (アルゴリズムを見つけるのは簡単です。Google はあなたの親友です)、各サブリストを繰り返し処理し、その値を合計します。

(apply + '(2 3))
=> 5

サブリストの合計の 1 つが期待値と等しい場合は、 を返し#tます。期待値を満たす合計がない場合は、 を返し#fます。

編集:

言及するのを忘れていましたが、これはよく知られた問題であり、動的計画法を使用して効率的に解決できる (少なくとも、べき集合を生成するよりも効率的に)サブセット和問題です。でも、それが特にこの宿題のゴールだとは思いません。

于 2013-03-28T01:14:06.043 に答える
0

これは、各要素を1つずつチェックし、最初の要素が合計でない場合はリストを再帰するソリューションです。

(define (numlist-sum list sum)
  (and (not (null? list))
       (let ((head (car list)))
         (cond ((number? head)
                (or (= sum head)
                    (numlist-sum (cdr list) sum)))
               ((list? head)
                (or (= sum (apply + head))
                    (numlist-sum (cdr list) sum)))
               (else 'ill-formed-list)))))

また、コードは次のように書き直すことができることに注意してください。

(define (numlist-sum? ls sum)
  (or (null? ls)
      (if (and (null? (cdr ls)) (equal? (car ls) sum))
      (equal? (car ls) sum)
      (equal? (cdr ls) sum)
      (equal? (apply + (car ls) (cdr ls)) sum)))

'(if pred #t else ...) の使用は少しぎこちなく、コードの真のロジックを隠していると思います。

于 2013-03-28T15:04:56.963 に答える