代码之家  ›  专栏  ›  技术社区  ›  Abdul Rauf

如何拼写球拍中的数字?(spellNum)[closed]

  •  -3
  • Abdul Rauf  · 技术社区  · 12 年前

    我是Racket的新手,我想写一个函数 spellNum 其执行以下操作:

    (spellNum 467) ---> '(four six seven)
    

    我不知道怎么开始。我已经通过查看在线文档开始编程,但我不知道如何在Racket博士中声明变量。我基本上是一个Python爱好者。有人能推我一下这个功能吗?

    (define (spellNum n)
      (if (number? n)
        (what should I do ?)
          null))
    
    3 回复  |  直到 12 年前
        1
  •  3
  •   Óscar López    12 年前

    编辑:

    已经发布了一个完整的解决方案,所以我想我可以向您展示如何编写惯用过程。请注意 number->list 使用称为尾部递归的技术来有效地表达循环。尽管(来自Python背景)使用显式循环构造(如@uselpa的答案所示)可能很诱人,但要真正理解Scheme的精神,您应该学习如何使用递归编写循环,这是用这种语言表达迭代的标准方法( 入乡随俗 ):

    (define (digit->symbol n)
      (case n
        ((0) 'zero)
        ((1) 'one)
        ((2) 'two)
        ((3) 'three)
        ((4) 'four)
        ((5) 'five)
        ((6) 'six)
        ((7) 'seven)
        ((8) 'eight)
        ((9) 'nine)
        (else (error "unknown digit:" n))))
    
    (define (number->list n)
      (let loop ((acc '()) (n n))
        (if (< n 10)
            (cons n acc)
            (loop (cons (remainder n 10) acc) (quotient n 10)))))
    
    (define (spellNum n)
      (map digit->symbol (number->list n)))
    

    诀窍是将问题分成不同的部分, digit->symbol 将单个数字转换为符号。类似地, 编号->列表 将数字转换为数字列表。在编写了这些助手程序之后,很容易编写 spellNum ,按预期工作:

    (spellNum 467)
    => '(four six seven)
    
        2
  •  1
  •   uselpa    12 年前

    正如奥斯卡所说,你真的应该学习特定于计划的习语。

    但是,由于来自Python,您可能会发现最初使用经典循环更容易,Racket也提供了这些循环。让我们构建一个特定于Racket的解决方案:

    第一 for/list 遍历一个序列(如列表、字符串,与Python的相同 for ... in construct)并构建列表:

    (define (spellNum n)
      (for/list [(c (number->string n))] 
        c))
    
    (spellNum 467)
    => '(#\4 #\6 #\7)
    

    这将生成一个字符列表。让我们再次将它们转换为字符串:

    (define (spellNum n)
      (for/list [(c (number->string n))] 
        (string c)))
    
    (spellNum 467)
    => '("4" "6" "7")
    

    现在,我们可以使用 string->number :

    (define (spellNum n)
      (for/list [(c (number->string n))] 
        (string->number (string c))))
    
    (spellNum 467)
    => '(4 6 7)
    

    最后,将这些转换为符号:

    (define (spellNum n)
      (for/list [(c (number->string n))] 
        (list-ref '(zero one two three four five six seven eight nine)
                  (string->number (string c)))))
    
    (spellNum 467)
    => '(four six seven)
    

    因此,整个过程可以用3-4行代码表示,但这也是Racket特有的。我强烈鼓励你学习Scheme的做事方式,这是一种更为普遍和非常有启发性的方法;-)

        3
  •  0
  •   beoliver    12 年前
    (require srfi/26)
    
    (define (spell-number n)
      (if (number? n)
          (let ([h (hash #\1 "one"
                          #\2 "two"
                          #\3 "three"
                          #\4 "four"
                          #\5 "five"
                          #\6 "six"
                          #\7 "seven"
                          #\8 "eight"
                          #\9 "nine"
                          #\0 "zero"
                          #\. "point" )])
                 (string-join (map (cut hash-ref h <>) (string->list (number->string n))) " "))
                 ;; else
                 "not a number"))