我正在编写一个函数来查找链表中所有出现的节点,该函数将返回主函数的出现次数,然后显示这些出现次数。该程序确实编译但它只是冻结,当我输入正确的名称来查找时似乎没有任何事情发生,如果我输入错误的名称,这不在列表中,findall函数返回0并且程序的其余部分工作精细。请看一下。
的main.cpp
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#include "List.h"
void extra(list &);
/***********************************
* Main
* Test function - DO NOT CHANGE
***********************************/
void main()
{
list a;
extra(a);
}
/***********************************
* Extra Credit
* Test function - DO NOT CHANGE
***********************************/
void extra(list &a)
{ int i,n;
node_ptr map[4];
string first,last;
// Find node
cout << endl;
cout << "Enter First and Last name: ";
cin >> first >> last;
n = a.findall(first,last,map,4);
// Display forwards
cout << endl;
cout << "Find List\n--------------\n";
for (i = 0; i < n; i++)
{
map[i]->put(cout);
}
}
List.h
#include "Node.h"
#include <iostream>
#include <string>
using namespace std;
class list
{ public:
list(); // Empty constructor
~list(); // Destructor
int findall(string, string, node_ptr*, int);
node *find(string, string); // Locate a note
private:
node *head;
};
Node.h
#include <iostream>
#include <string>
using namespace std;
class list;
class node
{ friend list;
public:
node(); // Null constructor
~node(); // Destructor
void put(ostream &out); // Put
private:
string first,last;
int age;
node *next;
};
typedef node * node_ptr;
List.cpp
#include "List.h"
#include <iostream>
#include <string>
using namespace std;
/**
* Empty Constructor
*
*/
list::list()
{
head = nullptr;
}
/**
* Destructor Constructor
*
*/
list::~list()
{ if (head == nullptr) return;
node *p = head, *t;
while (p)
{
t = p;
p = p->next;
delete t;
}
head = nullptr;
}
/**
* Locate node
*
*/
node *list::find(string last, string first)
{
node *temp = head;
while (temp)
{
if (temp->first == first && temp->last == last) return temp;
temp = temp->next;
}
return nullptr;
}
/**
* Find all.
*
*/
int list::findall(string first, string last, node_ptr* map, int n)
{
int ans;
ans = 0;
*map = find(first, last);
while (*map != NULL)
{
ans++;
*map = (*map)->next;
*map = find(first, last);
}
return ans;
}
Node.cpp
#include "Node.h"
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
/**
* Empty Constructor
*
*/
node::node()
{
last = "";
first = "";
age = 0;
next = nullptr;
}
/**
* Destructor
*
*/
node::~node()
{ if (next != nullptr) next = nullptr;
}
/**
* Put
*
*/
void node::put(ostream &out)
{ out << setw(14) << left << last << setw(14) << first << setw(10) << age << endl;
}
我非常感谢你的帮助。谢谢。
答案 0 :(得分:3)
findall()
冻结,因为它陷入无限循环。
如果找不到匹配的节点,则第一次调用find()
会返回nullptr
和findall()
退出。
但如果找到匹配的节点,则输入一个循环,调用find()
从头开始重新搜索整个列表。这将找到与以前相同的节点。然后再次呼叫find()
,再次呼叫,依此类推。
要解决此问题,如果find()
返回匹配的节点,则需要将以下调用中的next
节点传递给find()
,以便它可以开始搜索上一次搜索离开的位置关闭。重复,直到到达列表的末尾。
class list
{ public:
...
int findall(string first, string last, node_ptr *map, int n);
node_ptr find(string first, string last, node_ptr start = nullptr); // Locate a note
...
};
node_ptr list::find(string last, string first, node_ptr start)
{
node_ptr temp = (start) ? start : head;
while (temp)
{
if ((temp->first == first) && (temp->last == last)) break;
temp = temp->next;
}
return temp;
}
int list::findall(string first, string last, node_ptr* map, int n)
{
int ans = 0;
node_ptr temp = nullptr;
while (ans < n)
{
temp = find(first, last, temp);
if (!temp) break;
*map++ = temp;
++ans;
temp = temp->next;
}
return ans;
}
更新:如果您无法更改find()
的签名,则必须重新编写findall()
以复制find()
的内容:
class list
{ public:
...
int findall(string first, string last, node_ptr *map, int n);
node_ptr find(string first, string last); // Locate a node
...
};
node_ptr list::find(string last, string first)
{
node_ptr temp = head;
while (temp)
{
if ((temp->first == first) && (temp->last == last)) break;
temp = temp->next;
}
return temp;
}
int list::findall(string first, string last, node_ptr* map, int n)
{
int ans = 0;
node_ptr temp = head;
while (ans < n)
{
while (temp)
{
if ((temp->first == first) && (temp->last == last)) break;
temp = temp->next;
}
if (!temp) break;
*map++ = temp;
++ans;
temp = temp->next;
}
return ans;
}