首页 > 解决方案 > 在我的 Lisp 程序中简化分数的部分需要帮助

问题描述

当我完全不明白某些事情时,我通常会寻求帮助。

我的任务是制作一个 Common Lisp 程序,它将 2 个分数输入为 4 个单独的数字(n1 d1 n2 d2),并尽可能简化它。

我的第一个函数是以这种方式为分子 (n1 * d2) + (n2 * d1) 和分母 (d1 * d2) 添加分数。

然后第二个函数从第一个函数中获取分子和分母,然后从中计算 gcf。在这种情况下,我从互联网上复制了一个代码,因为我不知道如何实现它。

我目前卡住的第三个函数采用通过第二个函数和 gcf 的分子和分母,然后将分子和分母都除以 gcf,直到其中一个模 gcf 不再为零。

(defun simplify (n d dvs)
  (loop
    (setq n (/ n dvs)
          d (/ d dvs))
    (when (or (/= 0 (mod n dvs))
              (/= 0 (mod d dvs)))
      (setq n n d d)))
  (finalprint n d))

由于(return)不能返回超过 1 个值,我尝试过,(values n d)但程序会卡在没有做任何事情的情况下,对于(setq n n d d). 有什么想法可以解决这个问题吗?

标签: loopsrecursioncommon-lispfractions

解决方案


您可以尝试以下方法

(defun simplify (n d _gcd)
    (cons (/ n _gcd) (/ d _gcd)))

(defun add (n1 d1 n2 d2) 
    (let ((numerator (+ (* n1 d2) (* n2 d1)))
          (denominator (* d1 d2)))
      (simplify numerator denominator (gcd numerator denominator))))

(write (add 10 20 10 20)) ;;; (1 . 1)
(write (add 1 2 1 4)) ;;; (3 . 4)
(write (add 3 4 3 4)) ;;; (3 . 2)

gcd是 LISP 中的内置函数,因此您不必为此担心太多。let允许您命名 LISP 表达式,然后在后续表达式中使用它们。有关更多信息,请参阅

最后,您只需将分子和分母除以 gcd 一次,因为 if gcd(a, b) = d, then的属性gcd(a/d, b/d) = 1。有关更多信息,请查看


推荐阅读