反转给定整数的顺序 - 方案

Reverse the order of a given integer - Scheme

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

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

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

你的问题是 (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 并跟踪它做了多少次)或传递数字的长度(可能通过创建另一个函数来获取number n 作为参数并计算长度,然后将其传递给您的函数,然后该函数会在每次递归调用时从长度中减去 1。

你会得到这样的东西:

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

你得到的错误是因为在你的其他情况下,你做了 (n)。由于 n 不是过程,因此会出现错误。您只需要 n 即可。

您是否必须使用特定程序?如果没有,还有一种方法可以替代使用模数和相加的方法。这是关于使用列表过程,例如

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)) '())))
                  ))

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

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

; 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 是一个数字,因此您会收到错误消息。

重要的是要了解 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