2014-05-08 64 views
1

我想將使用遞歸輸入爲「1010」的二進制數字轉換爲10。我似乎無法圍繞使這個工作起作用的語法。DrRacket和遞歸語句二進制到十進制

(define (mod N M) 
    (modulo N M)) 

(define (binaryToDecimal b) 
    (let ([s 0]) 
    (helper b s))) 

(define (helper b s) 
    (if (= b 0) 
     (begin (+ s 0)) 
     (begin (* + (mod b 2) (expt 2 s) helper((/ b 10) + s 1))))) 

謝謝!

+1

(+ s 0)有點像s不是嗎? – stark

回答

3

這裏有一個簡單的遞歸解決方案:

(define (bin->dec n) 
    (if (zero? n) 
     n 
     (+ (modulo n 10) (* 2 (bin->dec (quotient n 10)))))) 

測試:

> (bin->dec 1010) 
10 
> (bin->dec 101) 
5 
> (bin->dec 10000) 
16 
+0

它應該是簡單的。我更喜歡這個答案。 –

0

如果你想"1010"翻譯成10(或#b1010#o12#xa)您實現string->number

(define (string->number str radix) 
    (let loop ((acc 0) (n (string->list str))) 
    (if (null? n) 
     acc 
     (loop (+ (* acc radix) 
       (let ((a (car n))) 
        (- (char->integer a) 
         (cond ((char<=? a #\9) 48)  ; [#\0-#\9] => [0-9] 
          ((char<? a #\a) 55)  ; [#\A-#\Z] => [10-36] 
          (else   87))))) ; [#\a-#\z] => [10-36] 
       (cdr n))))) 

(eqv? #xAAF (string->number "aAf" 16)) ; ==> #t 

它首先處理最高數字,每處理一個新數字,它將累加值乘以基數並添加新的「ones」,直到沒有更多字符。如果輸入"1010"和2的累計值從開始到結束爲0, 0*2+1, 1*2+0, 2*2+1, 5*2+0,最終將確保從右到左0..N編號的數字變成Sum(vn*radic^n)

現在,如果你需要一個過程,只做基地2個,然後製作一個包裝:

(define (binstr->number n) 
    (string->number n 2)) 

(eqv? (binstr->number "1010") #b1010) ; ==> #t 
+0

但是,爲什麼當它內置到Scheme時手動實現'string-> number'? –

+1

@ ChrisJester-Young我可以稱它爲'binstr-> number',並且具體說明它,但因爲我會使用'string-> number',但我可以實現它。感覺就像學習Scheme時實現'length'和'list'一樣。另外我正在計劃一個編譯器,這不是很難的部分,但是可能用'read-char'實現'read'是:-) – Sylwester