反转给定整数的顺序 - 方案
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
我在 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