反转给定整数的顺序 - Scheme

时间:2015-03-14 12:58:18

标签: recursion scheme racket

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

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

4 个答案:

答案 0 :(得分:2)

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

您的问题是,将(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

答案 1 :(得分:0)

您是否必须使用特定程序?如果没有,可以使用模数和添加数字。这是关于使用列表程序,如

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

答案 2 :(得分:0)

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

以下是将任务拆分为较小部分的一种方法:

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

答案 3 :(得分:0)

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