树递归/时间复杂度方案分配

时间:2008-10-23 03:10:43

标签: scheme

如果你能帮我解决这个问题的任何部分,我将不胜感激。感谢。

2^0 = 1
2^N = 2^(N-1) + 2^(N-1)
  1. 将此定义转换为完全等效的树递归函数,称为2-to-the-power。描述它的渐近时间复杂度,并解释为什么它具有这种时间复杂性。

  2. 现在编写一个名为tttpo_rec的函数,该函数计算完全相同的东西,但它使用线性递归过程,该过程具有O(n)时间复杂度,并且还使用O(n)空间进行挂起操作。

  3. 现在编写一个名为tttpo_iter的函数来计算完全相同的函数,但它使用的线性迭代过程具有O(n)时间复杂度并且还使用恒定空间。

  4. 现在让我们假设您想要推广上述定义之一,以便它可以处理任意整数幂,这样就可以计算2 ^ N,3 ^ N等。编写一个名为to-the-power的函数 - 这需要两个参数,并将一个参数提升到另一个参数的力量。

  5. 这是模板:

    ;; to-the-power-of: integer integer -> integer
    ;; This function raises m to the power of n, returning the result.
    ;; m must be > 0 and n >= 0.
    (define (to-the-power-of m n)
      ...)
    
    (check-expect (to-the-power-of 1 0) 1) ; base case
    (check-expect (to-the-power-of 2 3) 8) ; recursive case
    (check-expect (to-the-power-of 3 2) 9) ; recursive case
    

    我们将再添加一个限制:您不能使用*运算符;你只能使用下面的递归函数来进行乘法运算:

    ;;; multiply: integer integer -> integer
    ;; This function multiplies two non-negative integers, returning the result.
    ;; Its time complexity is O(a).
    (define (multiply a b)
      ...) 
    

    编写函数,并描述它的时间复杂度和原因。

2 个答案:

答案 0 :(得分:1)

哈哈哈。我不应该为人们做功课问题,但这太有趣了。 :-P

  1. 这只是天真的实施。我可以在不提出其余问题的情况下回答这个问题。

    (define (tttpo n)
      (if (zero? n) 1
                    (+ (tttpo (- n 1)) (tttpo (- n 1)))))
    

    显然这是一个非常愚蠢的实现,但是你被要求给它渐近的复杂性。

  2. 想想如何避免每次迭代调用tttpo两次。由于您被要求避免使用*,因此您可能需要隐藏tttpo的结果。

  3. 阅读尾递归。具体而言,您需要知道如何将一般递归算法转换为等效迭代(或尾递归,因为这是Scheme)版本。

  4. 一旦你为3编写代码就很明显了。(或者,请告诉我3的答案,我会进一步帮助你。)

  5. 祝你好运!

答案 1 :(得分:1)

第一个算法是O(2 ^ n),可以写成如下:

(define (2pow x)
  (if (= x 0) 1
      (+ (2pow (- x 1))
         (2pow (- x 1)))))

这可以在O(n)中重写如下:

(define (2pow x)
  (if (= x 0) 1
    (* 2 (2pow (- x 1)))))

由于Scheme使用尾调用优化,我们可以将其写成一个占用常量堆栈的尾递归函数:

(define (2pow x)
  (define (internal x accum)
    (if (= x 0) accum
        (internal (- x 1) (* accum 2))))
  (internal x 1))

广义:

(define (to-the-power-of a b)
  (define (internal x accum)
    (if (= x 0) accum
        (internal (- x 1) (* accum a))))
  (internal b 1))

编辑,因为我看到你不能使用*,你可以写自己的整数乘法:

(define (mult a b)
  (define (internal a accum)
    (if (= a 1) accum
        (internal (- a 1) (+ accum b))))
  (internal a b))

这是尾递归的,所以它在不断的堆栈空间中运行。只需在上述任何算法中用*替换*。

我还应该注意,所有这些函数都直接写入编辑器而未经过测试。使用风险自负