【问题标题】:Reverse the order of a given integer - Scheme反转给定整数的顺序 - 方案
【发布时间】:2015-03-14 12:58:17
【问题描述】:

我在 Scheme (Dr Racket) 中获得了一项任务,以反转给定数字的顺序。解决方案应该是递归的,这就是我到目前为止所得到的.. 事实是,我不太确定给定的算法是否有效,因为我得到: " 申请:不是程序; 期望一个可以应用于参数的过程” 每次运行都会出错。。 对这个问题有什么想法或帮助吗?

(define reverse-digits
     (lambda (n) (if (> n 9)
               (+ (* 10 (modulo n 10)) (reverse-digits (quotient n 10)))
               (n)))) 
(reverse-digits 1234)

【问题讨论】:

  • 你得到application: not a procedure的原因是因为你把n放在括号里,在这种情况下,这意味着你试图将n作为一个函数来调用。

标签: recursion scheme racket


【解决方案1】:

这是一个硬件作业,所以我不会给你代码。

您的问题是 (modulo n 10) 乘以 10 并不能让您到达您需要的位置。考虑 (reverse-digits 123)

(reverse-digits 123)
(+ 30 (reverse-digits 12))
(+ 30 (+ 20 (reverse-digits 1)))
(+ 30 (+ 20 1))
51

想要是每次根据数字的长度将其乘以 10 的不同幂。您可以创建一个计算数字长度的函数(可能通过重复将数字除以 10 并跟踪它执行了多少次)或传递数字的长度(可能通过创建另一个函数来获取编号 n 作为参数并计算长度,然后将其传递给您的函数,该函数将在每次递归调用时从长度中减去 1。

然后你会得到这样的东西:

(reverse-digits 123)
(+ 300 (reverse-digits 12))
(+ 300 (+ 20 (reverse-digits 1)))
(+ 300 (+ 20 1))
321

您遇到的错误是因为在您的其他情况下,您执行(n)。由于n 不是一个过程,你会得到一个错误。你只需要n

【讨论】:

  • 是的,你完全正确。不知道我怎么错过了。谢谢!
【解决方案2】:

您一定要使用特定的程序吗?如果不是,则可以使用模数和加数的替代方法。这是关于使用列表过程,例如

number->string

take

list->string

等等。

这是我的解决方案,它不是非常有效!

(define 
  invert-number-aux (λ (n res)
                  (if (empty? n) res
                      (invert-number-aux 
                       (take n (-(length n) 1)) ;new n
                       (append res (list (last n))) ;new res
                       )
                      )))
(define
  invert-number (λ (n)
                  (string->number (list->string (invert-number-aux (string->list(number->string n)) '())))
                  ))

【讨论】:

    【解决方案3】:

    使用较小的辅助函数会很有帮助。

    这是将任务拆分为更小部分的一种方法:

    ; number->digits : natural -> list-of-digits
    (define (number->digits n)
      ...)
    
    ; digits->number : list-of-digits -> natural
    (define (number->digits n)
      ...)
    

    使用这些助手,您可以编写:

    (define (reverse-number x)
       (digits->number
         (reverse
            (number->digits x))))
    

    另外 - 如果您想要错误“应用程序:不是过程;期望可以应用于参数的过程”,请将 (n) 替换为 n

    如果你在 DrRacket 中运行你的程序,应用程序 (n) 应该是红色的。问题是(42) 表示评估 42,然后像调用函数一样调用结果。由于 42 是一个数字,因此您会收到错误消息。

    【讨论】:

      【解决方案4】:

      重要的是要了解 fixnums 不只有一种表示形式,并且数字的不同数字可能会随着其表示形式的基础而改变。这是我的看法。

      (define (number->digits number (base 10))
        (let loop ((n number) (acc '()))
          (if (zero? n)
              acc
              (let-values (((res rem) (quotient/remainder n base)))
                (loop res (cons rem acc))))))
      
      (define (list->number lst (base 10))
        (foldl (lambda (x acc)
                 (+ (* acc base) x))
               0
               lst))
      
      (define (reverse-digits number (base 10))
        (list->number (reverse (number->digits number base))
                      base))
      
      (number->string (reverse-digits #b100111 #b10) #b10) ; ==> "111001" (or 39 => 57 in base 10)
      (number->string (reverse-digits #xebabefac #x10) #x10) ; ==> "cafebabe" (or 3953913772 => 3405691582 in base 10)
      (number->string (reverse-digits 1234)) ; ==> 4321
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-25
        • 1970-01-01
        • 2012-10-25
        • 2011-07-21
        • 2012-07-21
        • 1970-01-01
        • 2012-04-05
        • 1970-01-01
        相关资源
        最近更新 更多