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 的当前值的问题。我不知道该怎么做。此外,当我将第二个条件的答案保留为原始数据时(只是为了确保整个过程有效),我会收到“未指定的返回值”错误,我不确定为什么会发生这种情况,因为我的代码的其余部分循环(或者看起来如此?)提前感谢您对此的任何见解。

4

2 回答 2

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)))
于 2013-10-02T05:45:55.783 回答
0

首先,如果您不想捕获变量名,请在内部函数中使用不同的变量名。其次,与内置版本相比,我认为这些论点是错误的。(modulo 5 6) 是 5,(modulo 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)))))))))
于 2013-10-03T15:17:52.363 回答