(SCHEME): Dividing a bigint into tens, hundreds, ect. And into a list that contains english

纵饮孤独 提交于 2019-12-12 02:49:30

问题


So I'm having a hard time trying to write this program.
The scope is a program that will take a large number, (say 1,000,000) and split it into its digits (ie 1,500,310 -> 1 million 500 thousand 3 hundred 1 ten 0 one).

#lang r5rs 
(define (three_names x)
  (let loop ((x x)
             (myList '()))
    (if (< x 10)
        (cons x myList)
        (loop (quotient x 10)
              (cons (remainder x 10) myList)))))

I've gotten it so that it will loop and return these values each into a list with some help from stackoverflow.

(i.e. this will take say 100 and put it in '(1 0 0) which is helpful but not helpful enough. I've been banging my head since Wednesday!)


回答1:


I would go for something like this:

#lang r5rs 

(define (three-names n)
  (let loop ((n n)
             (units '((10 "one") (10 "ten") (10 "hundred") (1000 "thousand") (1000 "million")))
             (res ""))
    (if (or (zero? n) (null? units))
        res
        (let* ((unit (car units)) (div (car unit)) (txt (cadr unit)))
          (let ((q (quotient n div)) (r (remainder n div)))
            (loop q
                  (cdr units)
                  (string-append (number->string r) " " txt " " res)))))))

testing:

> (three-names 1500310)
"1 million 500 thousand 3 hundred 1 ten 0 one "
> (three-names 1001)
"1 thousand 0 hundred 0 ten 1 one "

EDIT

An alternative version that

  • works for the intial value 0 (the previous procedure wouldn't return anything in that case)
  • works with symbols and returns a list rather than a string, as asked in your comment
  • has an additional display in the loop that wlll make it clearer how the "units" are chosen:

could be:

(define (three-names n)
  (if (zero? n)
      "zero"
      (let loop ((n n)
                 (units '((10 one) (10 ten) (10 hundred) (1000 thousand) (1000 million)))
                 (res '()))
        (display n) (display " - ") (display res) (display " - ") (display units) (newline)
        (if (or (zero? n) (null? units))
            res
            (let* ((unit (car units)) (div (car unit)) (txt (cadr unit)))
              (let ((q (quotient n div)) (r (remainder n div)))
                (loop q
                      (cdr units)
                      (cons r (cons txt res)))))))))

now:

> (display (three-names 1500310))
1500310 - () - ((10 one) (10 ten) (10 hundred) (1000 thousand) (1000 million))
150031 - (0 one) - ((10 ten) (10 hundred) (1000 thousand) (1000 million))
15003 - (1 ten 0 one) - ((10 hundred) (1000 thousand) (1000 million))
1500 - (3 hundred 1 ten 0 one) - ((1000 thousand) (1000 million))
1 - (500 thousand 3 hundred 1 ten 0 one) - ((1000 million))
0 - (1 million 500 thousand 3 hundred 1 ten 0 one) - ()
(1 million 500 thousand 3 hundred 1 ten 0 one)


来源:https://stackoverflow.com/questions/35530887/scheme-dividing-a-bigint-into-tens-hundreds-ect-and-into-a-list-that-conta

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!