Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有更有效的多项式乘法方法?_Java_Polynomial Math - Fatal编程技术网

Java 有没有更有效的多项式乘法方法?

Java 有没有更有效的多项式乘法方法?,java,polynomial-math,Java,Polynomial Math,这是我将两个形式为an*x^n+an-1*x^n-1+…+的多项式相乘的方法a1*x+a0。每个术语对象有两个字段:双系数和整数幂多项式通过将术语存储在数组列表中来表示多项式。乘法的当前实现是O(n^2)。关于如何加快速度有什么想法或提示吗 public Polynomial multiply(Polynomial P2) { PolynomialImp result = new PolynomialImp(); for (Term currentThisTerm : this.

这是我将两个形式为
an*x^n+an-1*x^n-1+…+的多项式相乘的方法a1*x+a0
。每个
术语
对象有两个字段:
双系数
整数幂
<代码>多项式通过将术语存储在
数组列表
中来表示多项式。乘法的当前实现是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);
}
private void addTerm(Term nexterm)
{
for(int i=0;i
您有一个主要的低效之处:您将术语存储在一个看似无序的列表中。您应该修改代码,以便terms.get(n)返回带有x^n的术语。这样就不需要在addTerm方法中搜索terms变量

为此,您必须更新所有修改术语的代码,以保持术语的有序性


乘法方法本身看起来很有效,我不认为它可以进行更多的优化。

这就是我可能实现此功能的方式

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));
    }
}

可能是因为创建了n^2个TermImp对象,所以该算法的速度变慢了。在C++中,这不应该是个问题,因为你会在堆栈上创建对象并按值传递。我的理解是,在Java中,您没有这个选项:您必须接受创建对象的开销,然后通过引用传递

每次乘以一个项时都要创建一个新对象,这似乎效率低下。你就不能消除它吗

可以考虑更改AdTeNT方法,将系数和指数作为双/int参数。< /P> 对于较大的n,该算法仍然是O(n^2),但它应该仍然会加快很多


另一个你可以考虑的是使用for循环而不是迭代器,因为迭代器还涉及创建新对象…虽然O(n)不是那么关键。

我会使用双[]数组,每个功率的系数。这仍然是O(n^2)来执行乘法。你确定你需要它更快吗?我不需要它更快,但我想我可能会尝试学习和傻笑。多项式乘法是O(n^2),除非你使用FFT乘法是O(n^2)的最小值,但你的实现是-由于addTerm()中的内部循环-最坏情况下接近O(n^3)。在正常情况下,与计算多项式相比,确定结果多项式所用的时间应该相当短(假设您要计算多次)。因此,如果您还不知道Horner的方法(),那么您可能还会学到一些值得一看的东西。我知道这是在答案发布后很久才知道的,但我可以确认这是一种魅力!
[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]