list - 将数字转换为英文字母列表

标签 list scheme lisp racket

我有下面的函数,可以将数字输入转换为这些数字的部分翻译单词输出。

使用乘积和商,它在将数字分成组的同时添加数字的单词表示。

例如:

(number-name 87969087) -> '(87 million 969 thousand 87)
(number-name 1000000) -> '(1 million)

我试图通过完全翻译那些小于 1000 的数字来完成我的问题。我正在尝试实现一个小于 1000 的函数,该函数将在构建列表时显示那些较小的数字。旁边:

;; for less than 1000
; state words for 1-19
(define baseNumbers '(one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen))

; state words for multiples of ten
(define multiples '(twenty thirty forty fifty sixty seventy eighty ninety))

所以

(number-name 1110) -> '(one thousand one hundred ten)

也很难想出一种方法来显示输入 0 以显示为零,如果输入不是 0,则不显示零。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~

(define (number n)
  (define units '(thousand million billion trillion quadrillion))
  (define (nsplit n units acc lst)
    (define q (quotient n 1000))
    (define r (remainder n 1000))
    (if (zero? n) lst
        (cond [(zero? acc)
               (if (zero? r)
                   (nsplit q units (add1 acc) lst)
                   (nsplit q units (add1 acc) (cons r lst)))]
              [(zero? r)
               (nsplit q (cdr units) acc lst)]
              [else
               (nsplit q (cdr units) acc (cons r (cons (car units) lst)))])))
  (nsplit n units 0 empty))

最佳答案

您可以将整数分成 3 位数字组,将单位附加到每个组,然后进一步将 3 位数字组转换为符号列表,从而将整数转换为符号列表。这是一个示例实现:

(define (num->lst num)
  (define bases '(one two three four five six seven eight nine ten eleven twelve
                  thirteen fourteen fifteen sixteen seventeen eighteen nineteen))
  (define multiples '(twenty thirty forty fifty sixty seventy eighty ninety))
  (define units '(empty thousand million billion trillion quadrillion quintillion
                        sextillion septillion octillion nonillion decillion))
  (define (below-1000 num bases mults)
    (cond [(zero? num) empty]
          [(< num 20) (list (list-ref bases (sub1 num)))]
          [(< num 100) (list* (list-ref mults (- (quotient num 10) 2))
                              (below-1000 (remainder num 10) bases mults))]
          [else (list* (list-ref bases (sub1 (quotient num 100))) 'hundred
                       (below-1000 (remainder num 100) bases mults))]))
  (define (nsplit num lst units)
    (define q (quotient num 1000))
    (define r (remainder num 1000))
    (if (zero? num) lst
        (cond [(zero? r) (nsplit q lst (cdr units))]
              [else (nsplit q (append (below-1000 r bases multiples)
                                      (cons (car units) lst)) (cdr units))])))
  (if (zero? num) '(zero)
      (remove 'empty (nsplit num empty units))))

below-1000 将 1000 以下的数字转换为符号列表。 nsplit 将数字分成 3 位数字组并将单位附加到每个组,同时使用 below-1000 转换 3 位数字。

例如,

> (num->lst 0)
'(zero)
> (num->lst 1000000001)
'(one billion one)
> (num->lst 35579005)
'(thirty five million five hundred seventy nine thousand five)

关于list - 将数字转换为英文字母列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42660997/

相关文章:

Common Lisp 中的指针

c# - 如何检查 String 是否以列表中的内容结尾。 C#

c# - 如何将 AggregateException 展开为单个异常?

list - Haskell 检查 Int 列表是否完整

lisp - 在 Windows 中试用 "The Little Schemer"书中的示例

c - 如何实现延续?

lisp - 合并 2 个排序列表

java - IDE没有报错,但是ArrayList无法工作

scheme - 为什么这段代码可以正常工作?

scheme - 如何修复列表中近对总和的错误