簡體   English   中英

有沒有更有效的乘法多項式的方法?

[英]Is there a more efficient way of multiplying polynomials?

這是我的方法,用於將形式為an*x^n + an-1*x^n-1 + ... + a1*x + a0兩個多項式相乘。 每個Term對象具有兩個字段: double coefficientint power Polynomial通過將項存儲在ArrayList<Term>來表示多項式。 當前乘法的實現是O(n ^ 2)。 關於如何使其更快的任何想法或提示?

public Polynomial multiply(Polynomial P2) {
    PolynomialImp result = new PolynomialImp();
    for (Term currentThisTerm : this.terms)
    {
        for (Term currentP2Term : ((PolynomialImp) P2).terms)
        {
            result.addTerm(new TermImp(currentThisTerm.getCoefficient()*currentP2Term.getCoefficient(), currentThisTerm.getExponent() + currentP2Term.getExponent()));
        }
    }
    //Sort polynomial in decreasing exponent order
    return result.sort();
}

如果需要,下面是addTerm方法:

private void addTerm(Term nextTerm)
{
    for (int i = 0; i < this.terms.size(); i++)
    {
        if (this.terms.get(i).getExponent() == nextTerm.getExponent())
        {
            //Add the coefficients if the current term has the same exponent as a term that is already in the polynomial.
            //This preserves the sorting of the polynomial except during multiply.
            this.terms.set(i, new TermImp(this.terms.get(i).getCoefficient() + nextTerm.getCoefficient(), this.terms.get(i).getExponent()));
            return;
        }
    }
    //Avoid adding zeros to the polynomial.
    if (nextTerm.getCoefficient() != 0)
        this.terms.add(nextTerm);
}

這就是我可能會實現此功能的方式

public class Polynomial {
    private final double[] coeff;

    public Polynomial(double... coeff) {
        this.coeff = coeff;
    }

    @Override
    public String toString() {
        return Arrays.toString(coeff);
    }

    public Polynomial multiply(Polynomial polynomial) {
        int totalLength = coeff.length + polynomial.coeff.length - 1;
        double[] result = new double[totalLength];
        for (int i = 0; i < coeff.length; i++)
            for (int j = 0; j < polynomial.coeff.length; j++) {
                result[i + j] += coeff[i] * polynomial.coeff[j];
            }
        return new Polynomial(result);
    }

    public static void main(String... args) {
        Polynomial p1 = new Polynomial(1, 2, 3);
        System.out.println(p1 + "^2 =" + p1.multiply(p1));
        Polynomial p2 = new Polynomial(3, -1, -1);
        System.out.println(p1 + "*" + p2 + "=" + p1.multiply(p2));
    }
}

版畫

[1.0, 2.0, 3.0]^2 =[1.0, 4.0, 10.0, 12.0, 9.0]
[1.0, 2.0, 3.0]*[3.0, -1.0, -1.0]=[3.0, 5.0, 6.0, -5.0, -3.0]

可能使該算法變慢的是創建n ^ 2 TermImp對象。 在C ++中,這應該不成問題,因為您將在堆棧上創建對象並按值傳遞。 我的理解是,在Java中,您沒有此選項:您必須接受創建對象的開銷,然后按引用傳遞。

每次乘以一個術語都創建一個新對象似乎效率很低。 您不能消除它嗎?

您可以考慮更改addTerm方法以接受系數和指數作為double / int參數。

對於較大的n,該算法仍將為O(n ^ 2),但仍應加快很多速度。

您可以考慮的另一件事是使用for循環而不是迭代器,因為迭代器還涉及創建新對象……盡管O(n)並不那么重要。

您的主要效率低下:您將術語存儲在看起來是無序的列表中。 您應該修改代碼,以便term.get(n)返回帶有x ^ n的術語。 然后,您將不需要在addTerm方法中搜索term變量。

為此,您將必須更新所有修改術語的代碼以保持術語有序。

乘法方法本身看起來很有效,我認為它無法進行更多優化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM