我正在尝试编写将遍历链表的函数,其中节点表示多项式的项。每个节点包括系数字段(双重命名系数),功率(size_t命名功率)和链接(NodePtr * next)。该函数使用双变量值调用,它表示节点应具有的系数,以及size_t变量 i ,表示其功率。该函数应遍历链表,以查找具有幂 i 的节点。如果列表已包含具有幂i的节点,则应更改其系数以保持新值。如果之前没有具有功率i的节点,则应该将该项加上系数值。该列表应按电源排序(即,具有电源3的节点应该是列表中的节点3)。
下面是我到目前为止编写的代码,但它当前会生成以下错误:
Project 3.exe中0x0130D2FA处的未处理异常:0xC0000005:访问冲突写入位置0x0000000C。
我无法弄清楚错误产生的原因,所以这是我的第一个问题。第二个是我相信我的函数可能有一些逻辑错误,并且没有正确修改和创建新节点。
我已经被困了好几天了,如果没有这个功能,我就无法测试我的其他功能,所以任何帮助都将不胜感激!谢谢!
void Poly::setCoeff(double value, size_t i)
{
if (0 <= i){
Node* prev = new Node();
Node* curr = new Node();
Node* newNode = new Node();
newNode->coeff = value;
newNode->power = i;
curr = myHead; // Initialize curr to myHead;
if (curr != nullptr)
{
while (curr->next != nullptr && curr->power != i)
{
prev = curr;
curr = curr->next;
}
if (curr->power == i)
{
curr->coeff = value;
}
else if (curr->next == nullptr && i == curr->power + 1)
{
curr->next = new Node; // Creates a node at the end of the list
curr = curr->next; // Points to that node
curr->next = nullptr; // Prevents it from going any further
curr->power = i;
curr->coeff = value;
}
else
{
prev->next = newNode;
newNode->next = curr;
}
}
else
{
curr->next = newNode;
curr = curr->next;
}
}
else
{
throw std::out_of_range("Index out of range");
}
}
答案 0 :(得分:2)
这是一系列明确错误的假设,说明如何在C ++中管理动态内存,这会让你在这段代码中遇到麻烦堆。如果这不是一个学术练习,我会告诉你只需将它全部扔掉并使用:
std::map<size_t, double>
也称为:好东西。它几乎可以完成您需要完成此代码的所有操作。
但这是学术界的问题。像学术界的大多数事情一样,在你了解应该之前,它们会让你爬过战壕。因此,我将揭示您的代码中存在的缺陷,但只需说明一下,一旦您了解了所有这些,您将首先使用已经可用的工具努力不必首先执行此操作
换句话说,除非有人说我必须使用手工编码的链表实现,否则我会使用上面的地图。你不能(还),但知道它就在那里。
您的代码
您没有包含Node
的定义,但我只能假设它看起来像这样:
struct Node
{
double coeff;
size_t power;
Node *next;
};
这是否嵌套在class Poly
之内(如果后者可能应该也是如此)同样不清楚。这与问题并不完全相关,但是这里提到的是试图开车回家,当在SO上提问时,提供足够的信息来最小化可能影响你得到的答案的假设。
用你的代码:
void Poly::setCoeff(double value, size_t i)
{
if (0 <= i) // NOTE: not needed, unsigned, will always be i >= 0
{
Node* prev = new Node(); // NOTE: wrong. leaks memory.
Node* curr = new Node(); // NOTE: same as above
Node* newNode = new Node(); // NOTE: **may** leak (see below)
newNode->coeff = value;
newNode->power = i;
curr = myHead;
if (curr != nullptr) // OK: check for null good
{
// NOTE: should be checking `curr`, not curr->next
while (curr->next != nullptr && curr->power != i)
{
prev = curr;
curr = curr->next;
}
// NOTE: should check curr for NULL first.
if (curr->power == i)
{
curr->coeff = value;
}
// NOTE: same here. also,
else if (curr->next == nullptr && i == curr->power + 1)
{
// NOTE: this code path will leak newNode allocated at the
// top of the function.
curr->next = new Node;
curr = curr->next;
curr->next = nullptr;
curr->power = i;
curr->coeff = value;
}
else
{
prev->next = newNode;
newNode->next = curr;
}
}
else
{ // NOTE: this is where your mainline fault is coming from. you
// just validated curr can be NULL here (and will be on initial)
curr->next = newNode;
curr = curr->next;
}
}
// NOTE: this can't happen, as i can never be less than zero
else
{
throw std::out_of_range("Index out of range");
}
}
以下几点显而易见。
您的代码更改
setCoeff
成员需要插入新术语,如果保持排序,您将通过适当的枚举知道是否通过发现(a)超出您的指数,或者(b)清单的结尾,以先发生者为准。i
是size_t
值,表示对象计数是幅度。标准任务size_t
是无符号,这意味着它不能为负数。这意味着检查i >= 0
是没用的。 总是就是这样。首先让自己更轻松。提供一个Node
构造函数,通过参数设置节点,以便您可以停止使用该设置乱丢代码。这样,由于您在构造初始化所有成员变量,因此更容易阅读和更安全。
struct Node
{
Node *next;
double coeff;
size_t power;
Node(double coeff_, size_t power_, Node *next_=nullptr)
: coeff(coeff_), power(power_), next(next_)
{}
};
有了这个,事情会变得相当容易。上面的打卡列表可以通过以下更改来实现:
void Poly::setCoeff(double value, size_t i)
{
Node *prev = nullptr; // points to prior node
Node *curr = myHead; // points to current node
while (curr && curr->power < i)
{
prev = curr; // remember current node...
curr = curr->next; // ... then move to next node
}
// only allocate a new node if
// (a) we reached the end of the list (curr == NULL)
// (b) we reached a node with non match (will be larger exponent)
if (!curr || curr->power != i)
{
// **NOW** allocate the new node. we know we need one and we
// have a pretty solid idea where it goes.
Node *newNode = new Node(value, i, curr);
// if prev is set, then it means the new node goes somewhere
// *past* the head pointer otherwise it will become the new head.
if (prev)
prev->next = newNode;
else
myHead = newNode;
}
else
{ // found matching node
curr->coeff = value;
}
}
我真诚地希望它有所帮助,并希望您在到达The Good Stuff之前彻底挖掘残骸。它最终值得。
答案 1 :(得分:1)
我会使用std::map
跟进答案(正如WhozCraig的优秀答案所提到的):
#include <map>
#include <iostream>
typedef std::map<size_t, double> Polynomial;
void AddCoefficientAndPower(Polynomial& poly, double coeff, size_t power)
{
// This does everything your assignment asked for, except for implementing
// all of that linked list stuff
poly[power] = coeff;
}
using namespace std;
int main()
{
Polynomial myPoly;
// add the coefficient and power
AddCoefficientAndPower(myPoly, 3, 1);
AddCoefficientAndPower(myPoly, 4, 2);
AddCoefficientAndPower(myPoly, 9, 0);
AddCoefficientAndPower(myPoly, 6, 3);
// This one will replace the previous (4,2)
AddCoefficientAndPower(myPoly, 3, 2);
// write out the coefficients followed by the power
Polynomial::iterator it = myPoly.begin();
while (it != myPoly.end())
{
cout << it->second << "^" << it->first << "\n";
++it;
}
}
输出:
9^0
3^1
3^2
6^3
基本上,您的整个作业是AddCoefficent
中的一行C ++语句,它在地图中插入一个项目,并替换现有条目(如果存在的话)。
注意 - 没有内存泄漏,没有调用new
,没有崩溃等等。
此外,如果您的要求还包括任何积分功率值,则上述方法适用于负功率值,0功率值和正功率值。