乘法多项式/简化类似术语

时间:2011-02-18 19:53:03

标签: java

我几乎完成了一个多项式乘法的家庭作业,必须简化其类似的术语,从最高到最低。这两个陈述也已经排序。我的程序工作得很好,但是得到结果需要很长时间(比如我机器上的2分钟),而我用来提交它的网站说超出了时间限制。对于实际的乘法(这里没有显示),它只需要很少的时间,但是相似术语的组合需要一段时间。它包含1个链接列表,其中包含2个语句,即:

2 2 2 1 1 1 //means 2x^2 + 2x +  x
*
3 2 5 1 1 0 //means 3x^2 + 5x + 1

然后把它变成2 2 2 1 1 1 3 2 5 1 1 0进行处理。

任何人都知道我怎么能加速这一点?感谢。

    public MyLinkedList add(MyLinkedList combinedList ) {
    MyLinkedList tempCombinedList = new MyLinkedList();
    MyLinkedList resultList = new MyLinkedList();
    //check highest power now that its sorted.
    tempCombinedList=null;
    tempCombinedList = new MyLinkedList();
    int highestPower=0;

    //we need to find highest power
    for(int l=2;l<=combinedList.size();l=l+2) {
        if((Integer)combinedList.get(l)>highestPower) {
            highestPower=(Integer)combinedList.get(l);
            System.out.println("highest power is "+highestPower);
        }
    }

    int tempAddition=0;     
    while(highestPower!=-1) {
        for(int z=2;z<=combinedList.size();z=z+2) {
            if((Integer)combinedList.get(z)==highestPower) {
                tempAddition=tempAddition+(Integer)combinedList.get(z-1);
            }
        }
        if((tempAddition!=0)) { //we arent allowed to have a 0 coefficient in there....
            resultList.add(tempAddition);
            resultList.add(highestPower);
        }
        else if(((tempAddition==0)&&(highestPower==0))) { //unless the exponent is 0 too
            resultList.add(tempAddition);
            resultList.add(highestPower);
        }
        tempAddition=0; //clear the variable for the next roud
        highestPower--; //go down in power and check again.
        }
return resultList;

}

2 个答案:

答案 0 :(得分:3)

乘法多项式等于convolving个系数。不应该有任何单独的“简化”阶段。

卷积是 O(N ^ 2)时间复杂度(假设两个多项式都是长度 N )。如果 N 非常大,则可能值得考虑“快速卷积”,它通过FFT将卷积转换为逐元素乘法。这是 O(N log N),虽然缓存问题可能会在实践中扼杀你。

答案 1 :(得分:1)

您的代码看起来像是在使用具有交替因子和指数的列表。这可能不是您的性能问题的原因,但是使代码更难阅读 - 除了您的演员。

使用类似

的类
class Monomial implements Comparable<Monom> {
   private int exponent;
   private int factor;

   // TODO: get methods, constructor

   public int compareTo(Monomial other) {
       return this.exponent - other.exponent;
   }

   public Monomial times(Monomial other) {
      // here your multiplication code
   }


}

然后您可以使用List<Monomial>而不是整数列表。首先,这使您的代码更具可读性;其次,您现在可以(在乘法之后)简单地对列表进行排序,这样您以后就不必一次又一次地遍历整个列表。

然后,由于您始终使用.get(i)访问列表,请不要使用链表,请使用ArrayList(或类似结构)。 (对于链接列表,您对每个访问都必须遍历列表以获取所需的元素,而不是数组列表。)或者,使用Iterator(或增强的for循环)而不是index-access。 / p>


实际上,如果你在乘法之前对因子进行排序(并简化),你可以按照正确的顺序将它们相乘,这样你就不必在事后简化了。例如,它是

(2x^2 + 3x + 0) * (3x^2 + 5x + 1)
= (2*2) * x^4 +
  (2*5  + 3*3) * x^3 +
  (2*1 + 3*5 + 0*3) * x^2 +
  (3*1 + 0*5) * x^1 +
  (0*1) * x^0
= 4 * x^4 + 19 * x^3 + 17 * x^2 + 3 * x 

(你得到的方案:在每一行中,第一个多项式的因子向下排序,第二个多项式的因子向上排序。)

(如果你愿意的话,你可以在开头就放弃0条款。)