我正在尝试编写一个迭代过程来在方案中使用内置过程modulo,remainder或/在中进行模运算。但是在尝试编写代码时遇到了一些问题,到目前为止看起来像这样:
(define (mod a b)
(define (mod-iter a b)
(cond ((= b 0) 0)
((< b 0) (+ old_b new_b))))
(mod-iter a (- a b)))
正如您所看到的,我遇到了需要将b的原始值添加到b的当前值的问题。我不知道该怎么做。另外,当我把第二个条件的答案留给原始数据时(只是为了确保enitre程序有效),我会得到一个“未指定的返回值”错误,我不知道为什么会发生这种情况,因为我的其余代码循环(或者似乎?) 提前感谢您对此的任何见解。
答案 0 :(得分:0)
当您使用参数mod-iter
定义(a b)
函数时,您将隐藏mod
中定义的参数。要避免阴影,请使用不同的标识符:
(define (mod a b)
(define (mod-iter ax bx)
(cond ((= bx 0) 0)
((< bx 0) (+ b bx))))
(mod-iter a (- a b)))
注意,这看起来不像正确的算法(没有递归调用)。你如何处理(> bx 0)
的常见情况?你需要这样的东西:
(define (mod a b)
(define (mod-iter ax bx)
(cond ((= bx 0) 0)
((< bx 0) (+ b bx))
((> bx 0) ...))) ;; <- something here with mod-iter?
(mod-iter a (- a b)))
答案 1 :(得分:0)
首先,如果您不想捕获变量名,请在内部函数中使用不同的变量名。其次,我认为与内置版本相比,这些论点是错误的。 (模5 6)是5,(模6 5)是1.无论如何,这里是对数时间的变化。基于生成b(2 4 8 16 32 ...)的幂列表,b是2,一直到a的值之下。然后通过机会减去这些反转值。那样的问题(mod(expt 267 34)85)很快就会回答问题。 (几百个原始函数调用与几百万)
(define (mod a-in b-in)
(letrec ((a (abs a-in))
(sign (if (< 0 b-in) - +))
(b (abs b-in))
(powers-list-calc
(lambda (next-exponent)
(cond ((> b a) '())
((= next-exponent 0)
(error "Number 0 passed as the second argument to mod
is not in the correct range"))
(else (cons next-exponent (powers-list (* b next-exponent))))))))
(let ((powers-list (reverse (powers-list-calc b))))
(sign
(let loop ((a a) (powers-L powers-list))
(cond ((null? powers-L) a)
((> a (car powers-L))
(loop (- a (car powers-L)) powers-L))
(else (loop a (cdr powers-L)))))))))