【问题标题】:Polynomial operations using operator overloading使用运算符重载的多项式运算
【发布时间】:2010-03-11 14:00:04
【问题描述】:

我正在尝试使用运算符重载来为我的多项式类定义基本运算(+、-、*、/),但是当我运行程序时它崩溃并且我的计算机死机了。

更新4

好的。我成功做了三个操作,只剩下一个除法。

这是我得到的:

polinom operator*(const polinom& P) const
{
    polinom Result;
    constIter i, j, lastItem = Result.poly.end();
    Iter it1, it2, first, last;
    int nr_matches;

    for (i = poly.begin() ; i != poly.end(); i++) {
         for (j = P.poly.begin(); j != P.poly.end(); j++)
              Result.insert(i->coef * j->coef, i->pow + j->pow);
    }

    Result.poly.sort(SortDescending());

    lastItem--;

    while (true) {
        nr_matches = 0;

        for (it1 = Result.poly.begin(); it1 != lastItem; it1++) {
             first = it1;
             last = it1;
             first++;
             for (it2 = first; it2 != Result.poly.end(); it2++) { 
                  if (it2->pow == it1->pow) {
                      it1->coef += it2->coef;
                      nr_matches++;
                  }
             }

             nr_matches++;
             do {
                last++;
                nr_matches--;
             } while (nr_matches != 0);

             Result.poly.erase(first, last);
        }   
        if (nr_matches == 0)
            break;
    }     

    return Result;
}

【问题讨论】:

  • 编辑后问题变得完全不同。我不太明白,既然您永​​远不会让迭代器等于结尾,那么循环如何终止。
  • 我明白它为什么会停止,这是因为它会插入 3x^2,直到它最终耗尽内存并导致我的计算机崩溃。现在来看看如何解决它。
  • 你的“last”函数没有返回任何东西。这可能会导致问题。
  • 是的,马克,谢谢!

标签: c++ operations polynomial-math


【解决方案1】:
while (i != poly.end() || P.i != P.End())

我认为你需要 && ,否则只有当 i 和 p.i 同时到达它们各自的终点时循环才会终止。

带有否定的逻辑很棘手。可能更简单地认为这是:

while (!(i == poly.end() || j == P.End())) //while neither iterator has reached end

根据布尔算术等同于:

while (!(i == poly.end()) && !(j == P.End()))
while (i != poly.end() && j != P.End())

如果两者相等,您似乎也不会增加迭代器(无限循环导致无限多的内存分配?)。


样式问题:最好使用迭代器作为局部变量。如果变量应该在您开始在方法中使用它们之前“初始化”,则不要将它们设为类成员,并且在方法完成后它们变得无用。

还喜欢通过 const 引用传递参数,如果成员函数不修改当前对象(operator+ 不应该),则标记成员函数 const

 polinom operator+(const polinom& P) const;

(这将揭示制作本地使用的迭代器成员的问题 - 您将修改实例!)

【讨论】:

  • +1 用于样式问题。更好的风格带来更好的编程:)
  • 所以我应该摆脱 SetIterBegin()?
  • 是的,这也是不必要的。
  • 此外,如果您只是将条件更改为 &&,则崩溃可能会消失,但具有更多项的多项式不会在结果中包含所有项。在主循环之后,您需要检查两个迭代器并查看是否有剩余的项放入结果中。
  • @Mark: 崩溃的发生是因为当两者相等时没有放入 i++ 但我认为你是对的 ||在你的情况下更好。 @UncleBens:但是如果我通过 const Polinom 我不能增加 P 迭代器 ans alsi 为什么我应该通过 &Polinom?
【解决方案2】:

您的代码还有其他设计和正确性问题,但我认为崩溃发生在这一行

 if (i->pow > P.i->pow) 

当 i == poly.end() && P.i != P.End() 或 i != poly.end() && P.i == P.End()。当 i 指向最后一个元素之后取消引用会崩溃。

【讨论】:

    【解决方案3】:

    至于让函数正确地将多项式相加,我推荐这个简单的逻辑:

    polinom operator+(const polinom& P) const //fixed prototype re. const-correctness
    {
        polinom Result;
        std::list<term>::const_iterator //fixed iterator type
            i = poly.begin(), j = P.poly.begin();
    
        while (i != poly.end() && j != P.poly.end()) {
            //logic while both iterators are valid
        }
    
        //handle the remaining items in each list
        //note: at least one will be equal to end(), but that loop will simply be skipped
    
        while (i != poly.end()) {
            Result.insert(i->coef, i->pow);
            ++i;
        }
    
        while (j != P.poly.end()) {
            Result.insert(j->coef, j->pow);
            ++j;
        }
    
        return Result;
    }
    

    最后一部分可能也可以留给标准库函数

    #include <iterator>
    #include <algorithm>
    
    //...
        //handle remaining items in either list (if any)
         std::copy(i, poly.end(), std::back_inserter(Result.poly));
         std::copy(j, P.poly.end(), std::back_inserter(Result.poly));
    

    ...但使用list.insert 可能会更简单:

         Result.poly.insert(Result.poly.end(), i, poly.end());
         Result.poly.insert(Result.poly.end(), j, P.poly.end());
    

    【讨论】:

    • 使用您刚刚发布的内容,它会在任何输入时停止,而且如果我像这样插入它们,它不会从最高程度排序到最低程度。
    • 那个空循环是来填写的:)(基本上是你已经拥有的代码,没有试图让它完成整个工作的混淆)。
    • 但据我了解,您的代码并没有添加具有相同权力的术语并将它们按顺序排列,它只是将它们全部插入,对吗?
    • 不,第一个循环同时处理两个范围,确保保留顺序。它更简单,因为它可以安全地假设两个迭代器都是有效的。处理完该部分后,您将拥有未处理的列表(或没有)的最后一部分。然后,您可以将该部分附加到结果中。它将被订购,因为剩下的部分应该在公共部分之后。这是一个基本的合并算法。
    • 我想我现在明白了,我会测试它。再次感谢顺便说一句!
    猜你喜欢
    • 1970-01-01
    • 2011-01-26
    • 2015-03-13
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多