排序多项式Common Lisp

时间:2016-12-10 16:27:34

标签: sorting lisp common-lisp polynomials

我试图对以这种格式编写的多项式列表进行排序: (M [系数] [总度] [变量列表])。

示例:

((M 1 1 ((V 1 A))) (M 1 2 ((V 1 A) (V 1 C))) (M 1 2 ((V 2 A))) (M 1 2 ((V 1 A) (V 1 B))))

这是:a + a * c + a ^ 2 + a * b,我需要得到a + a * b + c + a * a ^ 2,因为a * b< a ^ 2和a< a ^ 2.

我尝试使用函数sort,但我的输出是:

((M 1 1 ((V 1 A))) (M 1 2 ((V 2 A))) (M 1 2 ((V 1 A) (V 1 B))) (M 1 2 ((V 1 A) (V 1 C))))

是a + a ^ 2 + a * b + a * c。

我用:

(defun sort-poly (a b)
  (cond 
    (t (sort-poly-helper (varpowers a) (varpowers b)))))

(defun sort-poly-helper (a b)
  (cond 
    ((null a) (not (null b)))
    ((null b) nil)
    ((equal (third(first a)) (third(first b))) (sort-poly-helper (rest a) (rest b)))
    (t (sort (list (third(first a)) (third(first b))) #'string-lessp))))

使用:

 (sort '((M 1 1 ((V 1 A))) (M 1 2 ((V 1 A) (V 1 C))) (M 1 2 ((V 2 A))) (M 1 2 ((V 1 A) (V 1 B)))) #'sort-poly)

有些帮助吗? 感谢

1 个答案:

答案 0 :(得分:3)

您对自己想要做的事情的定义是非常不透明的,难以提供答案。但是开始的方法是停止编程,就像它是1956年和使用一些抽象

首先,让我们定义如何创建变量并获取其位:

(defun make-variable (name &optional (degree 1))
  `(v ,name ,degree))

(defun variable-name (v)
  (second v))

(defun variable-degree (v)
  (third v))

现在让我们定义如何从变量列表中创建多项式。注意,多项式的总程度可以从所有变量的度数计算出来,所以我们这样做。

(defun make-polynomial (variables &optional (coefficient 1))
  ;; The total degree of the polynomial can just be computed from the
  ;; degrees of its variables
  `(m ,coefficient ,(reduce #'* variables :key #'variable-degree)
      ,variables))

(defun polynomial-coefficient (p)
  (second p))

(defun polynomical-total-degree (p)
  (third p))

(defun polynomial-variables (p)
  (fourth p))

现在,给定多项式列表,我们可以使用我们已经构建的抽象对它们进行排序:我们不需要使用列表访问器来浏览(实际上我们可以更改多项式或变量的表示形式)什么都不知道。)

我猜你想要排序的是多项式中变量的最高程度,虽然它不是很清楚,而不是多项式的总程度(这会更容易)。因此,让我们编写一个函数来提取最高变量:

(defun highest-variable-degree (p)
  (reduce #'max (mapcar #'variable-degree (polynomial-variables p))))

现在我们可以对多项式列表进行排序。

CL-USER 23 > (sort (list (make-polynomial (list (make-variable 'a)
                                               (make-variable 'b 2)))
                         (make-polynomial (list (make-variable 'c)
                                                (make-variable 'd))))
                   #'<
                   :key #'highest-variable-degree)
((m 1 1 ((v c 1) (v d 1))) (m 1 2 ((v a 1) (v b 2))))

请记住:不再是1956年