Lisp 力量之和

Lisp Sum of power

定义一个函数 "power" 接受两个输入参数 m 和 n,以及 returns m^n。然后,通过使用函数 "power",定义一个函数 sum_power 接受两个输入参数 m 和 n 和 returns 总和:(1^n + 2^n + 3^n + .... + m^n).

int 第一个函数我根据第二个函数中的给定参数计算幂和幂。但是程序报错:程序堆栈溢出。重启... 我找不到我的错误。函数power没问题我查了下

(defun power(m n)
  (let ((result 1))
    (dotimes (count n result)
      (setf result (* m result)))))

(defun sum_power (m n)
  (if (= 0 m)
      0
      (+ (powern m) 
         (sum_power (1- m) n))))

好的问题是你的函数 sum_power 当你传递变量 m 表达式 (- 1 m) 第一次是无限循环,因为例如

for m = 5 first time (- 1 m) => -4 (new m = -4) second time (- 1 m) => 5 (new m = 5)

重新开始,这是一个递归无限循环,您永远不会到达 1,所以这是溢出的情况

改用构建函数 (1- m) 来减小 m 的值,或者如果需要 (- m 1)

所以新函数将是这样的,而且这不是尾递归,所以对于大 m 和 n 会花费很多时间,但根据您的需要它应该可以工作,并且此函数的格式更好,请在编写 lisp 函数时采取 fromatting 以便于阅读

(defun sum_power (m n)
  (if (= 1 m)
      1
      (+ (power n m) (sum_power (1- m) n))

您的 sum_power 函数中存在参数顺序错误。当给定两个参数时,标准 lisp 函数 - 从第一个参数中减去第二个参数,即 (- 1 m) 将从一个中减去 m 而不是从 m 中减去 1,正如您可能预期的那样,因此您的结果将是一个负整数并且您的基本情况 (= 1 m) 将永远不会达到。为了使您的代码正常工作,您必须将参数交换为 - 因此 (- m 1) 或者您可以使用 lisp 函数 1- (1- m) 从其唯一参数中减去一个因此您的代码的更正版本如下:

(defun sum_power (m n)
   (if (= 1 m)
       1
       (+ (power m n) (sum_power (1- m) n))))

在不相关的旁注中,lisp 允许在函数、变量和宏名称中使用比大多数其他语言更多的字符,因此您可以使用 sum-power 而不是 sum_power,事实上它是可以说是更好的 lisp 风格使用连字符连接多词标识符名称而不是下划线(如在 C 中使用)或驼峰式大小写(如 Java 中使用的 sumPower)。其次,右括号通常不写在单独的一行上,而是与右括号前的最后一个表达式在同一行,正如我在上面的更正版本中所做的那样。这些只是惯例,如果您愿意,您可以遵循它们,但您没有义务。

为什么不用高阶函数和循环宏?我认为这样更具可读性:

(defun power (n m)
   (reduce #'* (loop for x below n collect m))

(defun sum-power (n m)
   (reduce #'+ (loop for x from 1 to m collect (power x n)))