我正在使用一个使用STL链表的Polynomial类。其中一个功能要求我将两个多项式一起添加。由于某种原因,+ =运算符似乎是复制节点,而不是仅仅修改内容。
这是类声明:
class Polynomial
{
public:
Polynomial(pair<double,int>); //Specified constructor
void add(const Polynomial&);
void print();
private:
Polynomial(); //Default constructor
list<pair<double,int> > terms;
};
这是添加成员函数:
void Polynomial::add(const Polynomial& rhs)
{
list<pair<double,int> >::const_iterator r;
list<pair<double,int> >::iterator l;
for(r=rhs.terms.begin(); r!=rhs.terms.end(); r++)
{
bool match=0;
//Check to see if we have an existing nth order node
for(l=terms.begin(); l!=terms.end(); l++)
{
//If we do, just add the coefficients together
if(l->second == r->second)
{
l->first += r->first;
match = 1;
}
}
//If there was no matching existing node, we need to find out
//where to insert it into the list.
if(!match)
{
l=terms.begin();
bool inserted=0; //Sentinel for the loop
while(l!=terms.end() && !inserted)
{
//If there's only one term in the list
//Just compare and stick it in front or behind the existing node
if(terms.size()==1)
{
int this_exp = l->second;
int exp_to_ins = r->second;
if(exp_to_ins > this_exp) terms.push_back((*r));
if(exp_to_ins < this_exp) terms.push_front((*r));
inserted = 1;
}
//If there's more than one node, we need to traverse the list
if(terms.size()>1)
{
if(l!=terms.begin())
{
int this_exp = l->second;
l++;
int next_exp = l->second;
int exp_to_ins = r->second;
//If the new node value is between the current and next node
//Insert between them.
if((this_exp < exp_to_ins) && (exp_to_ins < next_exp))
{
terms.insert(l,(*r));
inserted = 1;
}
}
else if(l==terms.begin())
{
int this_exp = l->second;
int exp_to_ins = r->second;
//This will be the smallest order node
//Put it in the top spot
if(this_exp > exp_to_ins)
{
terms.push_front((*r));
inserted = 1;
}
l++;
}
}
}
//If we've traversed the list and can't find the right place
//this must be the greatest order node in the list
//so just tack it on the end.
if(!inserted) terms.push_back((*r));
}
}
}
以正确的顺序对节点进行排序可以正常工作,但是我们有一个现有的n阶节点,而不是仅仅将系数加在一起,它保留了原始节点,但似乎是将第二个节点与系数相加,并且我不明白为什么。
如果我运行打印功能,那应该是F(x)= -2x ^ 7 + 3x ^ 6 - 11x ^ 5 - 2x ^ 4,相反我得到F(x)= -2x ^ 7 + 3x ^ 6 - 11x ^ 5 - 10x ^ 5。如果我调用列表中的size()函数,我得到4.但是如果我运行以下代码来打印列表中节点的信息:
stringstream test;
for(i=terms.end(); i!=terms.begin(); i--)
{
test << "Coefficient: " << i->first << " ";
test << "Exp: " << i->second << endl;
}
cout << "Size: " << terms.size() << endl;
cout << test.str();
以下是输出:
系数:-10 Exp:5 系数:-2 Exp:7 系数:3 Exp:6 系数:-11 Exp:5
非常感谢任何帮助。
编辑:这是测试程序。
Polynomial p(pair<double, int>(-10, 5));
p.add(Polynomial(pair<double,int> (-2,4)));
p.add(Polynomial(pair<double,int> (3,6)));
p.add(Polynomial(pair<double,int> (-2,7)));
p.add(Polynomial(pair<double, int> (-1,5)));
答案 0 :(得分:2)
你的add()
函数似乎是正确的,除了print:
for(i=terms.end(); i!=terms.begin(); i--)
{
test << "Coefficient: " << i->first << " ";
test << "Exp: " << i->second << endl;
}
这是完全错误的,并调用未定义的行为。 i
最初是terms.end()
,您是否取消引用它? items.end()
返回 past-the-end 迭代器。即使我假设它正确一段时间,条件i!=terms.begin()
意味着第一个元素永远不会打印!
所以修复就是这样:
for(list<pair<double,int> >::iterator i=terms.begin(); i!=terms.end(); i++)
{
test << "Coefficient: " << i->first << " ";
test << "Exp: " << i->second << endl;
}
它打印预期输出:
Size: 4
Coefficient: -2 Exp: 4
Coefficient: -11 Exp: 5
Coefficient: 3 Exp: 6
Coefficient: -2 Exp: 7
不正确吗?
您也可以在此处查看输出:http://www.ideone.com/p8mwJ
顺便说一句,代替add
,您可以改为operator+=
,而不是:{/ p>
const Polynomial& operator+=(const Polynomial& rhs)
{
//same code as before
return *this;
}
如果您这样写,那么您可以添加多项式:
Polynomial p(pair<double, int>(-10, 5));
p += Polynomial(pair<double,int> (-2,4));
p += Polynomial(pair<double,int> (3,6));
p += Polynomial(pair<double,int> (-2,7));
p += Polynomial(pair<double, int> (-1,5));
演示:http://www.ideone.com/aA1zF
我刚刚阅读了您的评论,并且知道您想要以相反的顺序打印它,在这种情况下,您可以使用rbegin()
和rend()
代替begin()
和{ {1}} as:
end()
我还建议你将for(list<pair<double,int> >::const_reverse_iterator i=terms.rbegin();
i!=terms.rend();
i++)
{
test << "Coefficient: " << i->first << " ";
test << "Exp: " << i->second << endl;
}
作为const函数:
print
更好的是重载void print() const
//^^^^ this makes the function const!
。
无论如何逆序打印演示:http://www.ideone.com/Vk6XB
答案 1 :(得分:0)
您的测试循环(字符串流中的一个打印)不正确:取消引用end()迭代器是未定义的行为。可能你的“std :: list”是以循环方式实现的(即使用begin == end + 1),因此解除引用“end”会让你在测试循环中开始。
使用反向迭代器以相反的顺序打印列表:
for (i = list.rbegin (); i != list.rend (); ++i)
{
test << "Coefficient: " << i->first ; // etc.
}
答案 2 :(得分:0)
除了@Nawaz指出的问题外,Polynomial::add
函数也存在问题。
如果执行了if(terms.size()==1)
块,则会在列表中插入新项目。但是这会将列表的大小增加一个,因此if(terms.size()>1)
块也将被执行。这可以再次插入相同的节点。
在while循环中进一步增加l
,继续使用下一个节点,而不检查它是否有效(即不与terms.end()
比较)。
可能会有更多这样的错误,但这些错误是在粗略一瞥之后出现的。