2013-10-02 53 views
0

我正在尝试编写一个迭代过程,以使用内置过程中的模,余数或/,在方案中执行模算术,而不使用。但是我遇到了一些问题,而试图写的代码,它看起来像这样至今:重复减法迭代模?

(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

什么是'old_b'和'new_b'? –

+0

请注意,这只是一次内部定义的使用是一个很好的地方使用“命名让”,如@ÓscarLópez的[最近的答案](http://stackoverflow.com/a/19084091/1281433)所示。 –

回答

0

当您使用参数(a b)定义mod-iter函数时,您正在映射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

可以使用'else',因为如果它不相等或更低,它必须更高。 – Sylwester

+1

'mod'结尾对'mod-iter'的调用不正确;它不能访问任何'ax'或'bx'。那些应该是'a'和'b',不是? –

+0

我意识到我可以使用'else',但是这显式枚举了所有的数字可能性。谢谢。 – GoZoner

0

首先,如果你不想捕获一个变量名称,在内部函数中使用不同的变量名称。其次,我认为与内置版本相比,论据是错误的。 (模5 6)是5和(模6 5)是1.无论如何,这是在一个逻辑时间的变化。基于生成b(2 4 8 16 32 ...)的权力列表的基础是b是2,一直到刚好低于a的值。然后通过机会性减去这些反转的值。那样的问题(mod(expt 267 34)85)会很快返回答案。 (几百原始函数调用vs几百万)

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