如果你能帮我解决这个问题的任何部分,我将不胜感激。感谢。
2^0 = 1
2^N = 2^(N-1) + 2^(N-1)
将此定义转换为完全等效的树递归函数,称为2-to-the-power。描述它的渐近时间复杂度,并解释为什么它具有这种时间复杂性。
现在编写一个名为tttpo_rec的函数,该函数计算完全相同的东西,但它使用线性递归过程,该过程具有O(n)时间复杂度,并且还使用O(n)空间进行挂起操作。
现在编写一个名为tttpo_iter的函数来计算完全相同的函数,但它使用的线性迭代过程具有O(n)时间复杂度并且还使用恒定空间。
现在让我们假设您想要推广上述定义之一,以便它可以处理任意整数幂,这样就可以计算2 ^ N,3 ^ N等。编写一个名为to-the-power的函数 - 这需要两个参数,并将一个参数提升到另一个参数的力量。
这是模板:
;; 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)
...)
编写函数,并描述它的时间复杂度和原因。
答案 0 :(得分:1)
哈哈哈。我不应该为人们做功课问题,但这太有趣了。 :-P
这只是天真的实施。我可以在不提出其余问题的情况下回答这个问题。
(define (tttpo n)
(if (zero? n) 1
(+ (tttpo (- n 1)) (tttpo (- n 1)))))
显然这是一个非常愚蠢的实现,但是你被要求给它渐近的复杂性。
想想如何避免每次迭代调用tttpo
两次。由于您被要求避免使用*
,因此您可能需要隐藏tttpo
的结果。
阅读尾递归。具体而言,您需要知道如何将一般递归算法转换为等效迭代(或尾递归,因为这是Scheme)版本。
一旦你为3编写代码就很明显了。(或者,请告诉我3的答案,我会进一步帮助你。)
答案 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))
这是尾递归的,所以它在不断的堆栈空间中运行。只需在上述任何算法中用*替换*。
我还应该注意,所有这些函数都直接写入编辑器而未经过测试。使用风险自负