这是我将an*x^n + an-1*x^n-1 + ... + a1*x + a0
形式的两个多项式相乘的方法。每个Term
对象都有两个字段:double coefficient
和int 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);
}
答案 0 :(得分:4)
这就是我实现此功能的方法
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]
答案 1 :(得分:1)
可能使这个算法变慢的原因是创建n ^ 2个TermImp对象。在C ++中,这应该不是问题,因为您将在堆栈上创建对象并按值传递。我的理解是,在Java中你没有这个选项:你必须接受创建一个对象的开销,然后通过引用传递。
每次乘以一个术语时,创建一个新对象似乎效率低下。难道你不能消除它吗?
您可以考虑更改addTerm方法以接受系数和指数作为double / int参数。
对于大n,算法仍然是O(n ^ 2),但它仍然应该加速很多。
你可以考虑的另一件事是使用for循环而不是迭代器,因为迭代器也涉及创建新对象......虽然O(n)因此不那么重要。
答案 2 :(得分:0)
您有一个主要的低效率:您将条款存储在看似无序的列表中。您应该修改代码,以便terms.get(n)返回带有x ^ n的术语。然后,您不需要在addTerm方法中搜索terms变量。
为此,您必须更新修改条款的所有代码以保持条款的有序性。
乘法方法本身看起来很有效,我认为它不能再进行优化。