2016-05-01 10 views
0

再帰を使用して解決する必要があるとの問題を発見しました。問題は、ある特定の数字が与えられた場合、それに含まれる8の数を数えるべきですが、2つの8が隣にある場合、それは倍数として数えられるべきです。たとえば:数字の出現回数の再帰

48 should return 1 
    4881 should return 4 
    8818 should return 5 

私はスキームで次のプログラム作った:

(define (count n) 
    (if (= n 0) 
     0 
     (begin 
     (if (= (remainder n 100) 88) 
      2 
      (begin 
       (if (= (remainder n 10) 8) 
        1 
        0)) 
      ) 
     (+ (count (quotient n 10)))))) 

を問題は、私はそれを実行するたびに、私は何をしないのです、0を返すということですか?私はリストやセットを使用したくない!補助変数を使用する場合。どんな助け?

+1

は、私はあなたが必要とは思わない 'begin's .. – thebjorn

+0

..しかし、あなたは中間の答えに再帰する必要があります(と、どこかあなたは商を定義したい場合があります..?) – thebjorn

答えて

1

一致が見つかるたびに反復を続ける必要があり、合計が正しくないように見えます。また、代わりにif Sを入れ子のは、このように、condを使用することをお勧めします:

(define (count n) 
    (cond ((= n 0) 0) 
     ((= (remainder n 100) 88) 
     (+ 4 (count (quotient n 100)))) 
     ((= (remainder n 10) 8) 
     (+ 1 (count (quotient n 10)))) 
     (else 
     (+ (count (quotient n 10)))))) 

それはあなたの例で動作します:

(count 48) 
=> 1 
(count 4881) 
=> 4 
(count 8818) 
=> 5 
0

ヘルパーに8Sのスキャンをカウントしておく方が良いでしょう現在のヒット件数と過去のスキャンの合計得点を表示します。

(define (funny-eights n) 
    (define (aux n cur total) 
    (cond ((= (remainder n 10) 8) 
      (aux (quotient n 10) (+ cur 1) total)) 
      ((> cur 1) 
      (aux (quotient n 10) 0 (+ total (* 2 cur)))) 
      ((= cur 1) 
      (aux (quotient n 10) 0 (+ total cur))) 
      ((> n 0) 
      (aux (quotient n 10) 0 total)) 
      (else 
      total))) 
    (aux n 0 0)) 

(funny-eights 488838288) ; ==> 11 or 3*2 + 1 + 2*2 
関連する問題