2016-02-27 22 views
1

好的。所以我想知道如何創建一個將隨機數字轉換爲英文單詞組件的函數。(SCHEME)編號 - >英文列表

如(1001 - >「(一千)或0 - >」(零) 和(數名階乘20 - >「(二三次方432萬億902 兆8個十億1.76億六百 四萬))

我對計算器以前用戶合作,得到的東西,變成一個長數爲3點部分的數字(1341100是百萬,341000 1百0數萬0的人)

#lang r5rs 
(define (three-names n) 
    (if (zero? n) 
    "zero" 
    (let loop ((n n) 
      (units '((10 one) (10 ten) (10 hundred) (1000 thousand) (1000 million) (1000 billion) (1000 trillion) (1000 quadrillion) (1000 quintillion) 
          (1000 sextillion) (1000 septillion) (1000 octillion) (1000 nonillion) 
          (1000 decillion) (1000 undecillion) (1000 duodecillion) (1000 tredecillion) 
          (1000 quatturodecillion) (1000 sexdillion) (1000 septendecillion) (1000 octodecillion) 
          (1000 novemdecillion) (1000 vigintillion))) 
      (ARRAY '())) 

    (if 
    (or (zero? n) (null? units)) 
     ARRAY 
     (let* ((unit (car units)) (div (car unit)) (english (cadr unit))) 
      (let 
       ((q (quotient n div)) (r (remainder n div))) 
      (loop q 
        (cdr units) 
        (cons r (cons english ARRAY)))))))))  

我唯一理解的現在是讓這個有值0-20:

(= x 0) zero 
(= x 1) one 
... 
(> x 1000) thousand 
(> x 1000000) million 

但對一個,這些將不會被輸出到一個和兩個名單,不知道還能做什麼?

+0

而且這是怎麼從你的[前一個問題]不同的(http://stackoverflow.com/q/35530887/201359)? –

+0

輸出是相似的,但非常不同。而不是有3個數字後跟佔位符(數千或數十),它是整個返回的字符串 – Anitun

回答

1

由於Sylwester解釋了你需要能夠

  1. 正確打印文本低於1000每隔數(3位)
  2. 鴻溝3位數組的數量,使用上面的代碼打印出來,並只是追加「千」足以

下面是一個示例實現是與球拍的R5RS語言兼容:

(define (n2t n) 
    (define 1to19  '(one two three four five six seven eight nine ten eleven twelve 
          thirteen fourteen fifteen sixteen seventeen eighteen nineteen)) 
    (define multof10 '(twenty thirty forty fifty sixty seventy eighty ninety)) 
    (define thousands '(thousand million billion trillion quadrillion quintillion sextillion septillion octillion nonillion decillion undecillion)) 
    (cond 
    ((= n 0) '(zero)) ; zero is a special case since from now on all 0 will be suppressed 
    ((< n 0) (cons 'minus (n2t (- n)))) 
    (else 
    (let loop ((n n) (units thousands) (res '())) 
     (cond 
     ; --- below 1000 
     ((= n 0) res) 
     ((< 0 n 20) (cons (list-ref 1to19 (- n 1)) res)) 
     ((< n 100) (cons (list-ref multof10 (- (quotient n 10) 2)) 
          (loop (remainder n 10) '() res))) 
     ((< n 1000) (loop (quotient n 100) 
          '() 
          (cons 'hundred (loop (remainder n 100) '() res)))) 
     (else 
      ; --- 1000 and above 
      (let ((q (quotient n 1000)) 
       (res (loop (remainder n 1000) thousands res))) 
      (if (zero? q) 
       res 
       (loop q (cdr units) (cons (car units) res)))))))))) 

測試:

> (n2t 0) 
'(zero) 
> (n2t 1001) 
'(one thousand one) 
> (n2t 132219) 
'(one hundred thirty two thousand two hundred nineteen) 
> (n2t -132219) 
'(minus one hundred thirty two thousand two hundred nineteen) 
> (n2t 2345678213) 
'(two billion three hundred forty five million six hundred seventy eight thousand two hundred thirteen) 
> (n2t 2432902008176640000) 
'(two quintillion four hundred thirty two quadrillion nine hundred two trillion eight billion one hundred seventy six million six hundred forty thousand) 
+0

嗯...我無法得到這個工作。 define:不允許在第一個'define'函數的表達式上下文中使用。 – Anitun

+0

哦,我明白了,我失去了R5RS與我上次編輯的兼容性......現在已經修復了。 – uselpa

+0

真棒這有助於很多。 @uselpa 我想弄清楚如何放入析因函數。所以我在第一部分定義了一個函數。據我所知,它會計算它,但不會將它變成列表。 所以說我有(n2t(階乘3)) - >(六)。 我該如何着手將這個階乘函數添加到主代碼中並返回列表?它只需要首先計算值然後繼續進入該循環? – Anitun

1

正如你可能知道,你應該能夠做這樣的事情:

(number->english 2345678213) 
; ==> "two billion three hundred and fourtyfive million six \ 
;  hundred and seventyeight tousand two hundred and thirteen" 

起初glimse你可以看到,是有規律可循:

... 
<english number text below 1000> million 
<english number text below 1000> thousand 
<english number text below 1000> 

這樣..程序便叫看起來是這樣的:

(define (number->english x) 
    (if (zero? x) 
     "zero" 
     (iterate-thousands x thousands '())) 

thousands被定義爲:'("" "thousand" "million" "billion" "trillion" ...)iterate-tousands或許是這個樣子:

(define (iterate-thousands thousands x acc) 
    (if (zero? x) 
     (join acc " ") 
     (iterate-thousands (cdr thousands) 
         (quotient x 1000) 
         (list* (below-1000 (remainder x 1000)) 
           (car thousands) 
           acc)))) 

below-1000返回正確的字符串爲低於1000每個數根據命名約定,它通常會分工。這對於13歲以下的青少年是特別的,直到19歲的青少年,將青少年+青少年組合到99,並且對於上面的遞歸可能是+「100」+遞歸,因此234變成(string-append "two hundred and " (below-1000 34))join只需使用帶分隔符的string-append並正確處理空字符串。

+0

所以我將不得不遍歷每個數字?就像我想要數百萬人一樣,我必須遍歷數百萬,十萬,一萬,十萬。如果數字大於1000,該怎麼辦? – Anitun

+0

對不起,有點不好的問題。你有沒有一個看起來如何的例子?我很難想象 – Anitun

+0

@anitun那個迭代的整個代碼都在那裏。它以1000^0開始反向。我唯一遺漏的是'低於1000',這很有趣。 – Sylwester