(计划)编号 - >英文清单

时间:2016-02-27 07:24:08

标签: scheme racket number-formatting r5rs

好。所以我想知道如何创建一个将随机数转换为英语单词组件的函数。

如(1001 - >'(一千一)或0 - >'(零) 和(数字名称因子20 - >'(两个quintillion四百三十二千万亿九百二十 万亿八十亿七千六百六十万 四万))

我在stackoverflow上与之前的用户合作,将一个长数字转换成3个数字(1,341,100是100万,341千1 0 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

但是对于其中一个,这些不会输出到列表和两个,不知道还能做什么?

2 个答案:

答案 0 :(得分:1)

正如您可能知道的那样,您应该能够做到:

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

首先,你可以看到有一种模式:

...
<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岁,将ty + 1复合到99,并且可能是上面的递归,其中包括+&#34;百&#34; +余数的递归,以便234变为(string-append "two hundred and " (below-1000 34))join只需将string-append与分隔符一起使用,并正确处理空字符串。

答案 1 :(得分:1)

正如Sylwester所说,你需要能够

  1. 正确打印1000(3位数)以下每个数字的文本
  2. 将数字除以3位数组,使用上面的代码打印出来,只需添加“数千”即可。
  3. 这是一个与Racket的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)