Scheme Tonumber函数(Tonumber‘;(一二三)——>;123

Scheme Tonumber函数(Tonumber‘;(一二三)——>;123,scheme,racket,Scheme,Racket,在解决了之后,现在我试着写一个与这个函数相反的函数 (tonumber ‘(one two three) --> 123 到目前为止,我已经编写了这个工作代码 (define (symbol->digit n) (case n ('zero 0) ('one 1) ('two 2) ('three 3) ('four 4) ('five 5) ('six 6) ('seven 7) ('eight 8)

在解决了之后,现在我试着写一个与这个函数相反的函数

(tonumber ‘(one two three) --> 123
到目前为止,我已经编写了这个工作代码

(define (symbol->digit n)
  (case n
    ('zero 0)
    ('one 1)
    ('two 2)
    ('three 3)
    ('four 4)
    ('five 5)
    ('six 6)
    ('seven 7)
    ('eight 8)
    ('nine 9)
    (else (error "unknown symbol:" n))))



(define (numlist n)
  (map symbol->digit  n))



(numlist '(one two three))
从numlist中,我得到了'(1 2 3)。但是,下面的函数中存在一些问题,我想将列表转换为数字

(define (list->number l)
  (set! multiplier (* 10 (lenght l)))
  (for/list [(c l)] 
    (* multiplier c))
  (set! multiplier (/ multiplier 10)))

(list->number '(1 2 3))
任何帮助都将不胜感激。我无法在网上找到所有类型循环的文档。在


我想熟悉Racket,所以我想避免内置的转换函数。在列表->数字中,我试图从列表中一个接一个地提取数字,然后根据列表的长度将它们乘以101001000。这样它就可以返回一个数字。例如“(1 2 3)=1*100+2*10+3*1

这是与我的完全相反的,再次对
列表->number
过程使用尾部递归:

(define (symbol->digit n)
  (case n
    ('zero "0")
    ('one "1")
    ('two "2")
    ('three "3")
    ('four "4")
    ('five "5")
    ('six "6")
    ('seven "7")
    ('eight "8")
    ('nine "9")
    (else (error "unknown symbol:" n))))

(define (symbols->number symb)
  (string->number (string-join (map symbol->digit symb) "")))

(symbols->number '(one two three))
(define (symbol->digit n)
  (case n
    ('zero 0)
    ('one 1)
    ('two 2)
    ('three 3)
    ('four 4)
    ('five 5)
    ('six 6)
    ('seven 7)
    ('eight 8)
    ('nine 9)
    (else (error "unknown symbol:" n))))

(define (list->number lst)
  (let loop ((acc 0) (lst lst))
    (if (null? lst)
        acc
        (loop (+ (car lst) (* 10 acc)) (cdr lst)))))

(define (toNumber lst)
  (list->number (map symbol->digit lst)))
它按预期工作:

(toNumber '(four six seven))
=> 467
为了好玩,在Racket中,我们可以使用编写一个函数,如
list->number
。尽管如此,请注意,我们并没有在任何地方使用
set!
,在Python这样的语言中,变异状态是标准的,但在Scheme中,尤其是Racket中,我们尽量避免在循环中修改变量-有更优雅的方式来表示变量解决方案:

(define (list->number lst)
  (for/fold ([acc 0]) ([e lst])
    (+ e (* 10 acc))))

给猫剥皮的方法很多。这里有一个版本使用了
左折
。就像奥斯卡的解决方案一样,它使用的是数学,而不是字符和字符串

#!r6rs
(import (rnrs))

;; converts list with worded digits into
;; what number they represent.
;; (words->number '(one two zero)) ==> 120
(define (words->number lst)
  (fold-left (lambda (acc x)
               (+ x (* acc 10)))
             0
             (map symbol->digit lst)))

对于
#!racket
版本,只需将
foldleft
重命名为
foldl
,并切换
x
acc

的顺序,我想如果你花时间理解其他问题的答案,那么这个问题的答案将是你自己的。这是一个狡猾的编辑!我不确定你是否拒绝使用
la语言
构成了对语言的熟悉…感谢您的快速回复。您能告诉我循环是如何工作的吗?我知道什么是car、cdr和null?让我在线查找循环,但我使用的是循环。在循环中,
e
对每个元素进行迭代,
acc
累积答案,查看链接了解更多示例