问题
I'm writing writing polynomial arithmetic in lisp, and currently working on addition. I need help sorting a polynomial by the exponent and symbol. My polynomials are represented as follows:
((3 ((1 x)(1 y))) (1 ((3 y)))) ; == 3xy + 1y^3
The function I need guidance with is given a term like
((5 ((3 x))) (3 ((3 y))) (4 ((2 z)))) ((6 ((3 x))) (1 ((3 y))) (9 ((2 z)))))
I would want:
((4 ((2 Z))) (9 ((2 Z))) (5 ((3 X))) (6 ((3 X))) (3 ((3 Y))) (1 ((3 Y))))
returned, so that all So all z^2 and z^2 are together.
回答1:
Your initial example shows terms with two variables (e.g., 3xy), but your example later on doesn't. This solution won't handle the multiple variable term case (and you haven't said how you'd want grouping in that case anyhow), but it will handle your example.
First, define some abstractions for working with your polynomial terms, because they're rather inconvenient at the moment. Here are three functions that make it much easier to extract the coefficient, degree, and variable from each term:
(defun polynomial-term-coefficient (term)
(destructuring-bind (coefficient ((degree variable))) term
(declare (ignore degree variable))
coefficient))
(defun polynomial-term-degree (term)
(destructuring-bind (coefficient ((degree variable))) term
(declare (ignore coefficient variable))
degree))
(defun polynomial-term-variable (term)
(destructuring-bind (coefficient ((degree variable))) term
(declare (ignore coefficient degree))
variable))
Then, as I understand your question, you're actually starting with two polynomials 5x3 + 3y3 + 4z2 and 6x3 + y3 + 9z2. You'd add those together first, just by appending the list of their terms. Then you can sort that on the predicate string> (which takes string designators, so symbols are OK), with a key function of polynomial-term-variable. That is, you use the key function to extract the value that you actually want to sort by.
(let ((p1 '((5 ((3 x))) (3 ((3 y))) (4 ((2 z)))))
(p2 '((6 ((3 x))) (1 ((3 y))) (9 ((2 z))))))
(let ((unsimplified-sum (append p1 p2)))
(sort (copy-list unsimplified-sum) 'string> :key 'polynomial-term-variable)))
;=> ((4 ((2 Z))) (9 ((2 Z))) (3 ((3 Y))) (1 ((3 Y))) (5 ((3 X))) (6 ((3 X))))
回答2:
You might want to have a search for "Horner's method", which is an old numerical method for computing the value of a polynomial in O(n) time, n being the number of terms. It looks from the outset that's close to what you want to do, or at least similar in representation.
来源:https://stackoverflow.com/questions/34043236/sort-polynomial-based-on-symbol-and-exponent