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]