我正在学习c ++并试图按字母顺序维护链表。如果我要输入一个名单“Mary,bob,sally,larry,david,roger”,我希望他们打印出来(在浏览列表之后)“bob,david,larry,mary,roger,sally”。任何帮助将不胜感激。谢谢!
注意:当我尝试执行代码时,代码不按字母顺序打印名称。道歉,我写道,但显然我没有。它编译得很好,但产生的结果并不是预期的结果。
编辑:我发现了一些有趣的东西。我尝试构建文件时遇到错误c:/mingw/bin/../lib/gcc/mingw32/4.9.3/../../../../mingw32/bin/ld.exe: cannot open output file Program18ContactList.exe: Permission denied collect2.exe:error: 1d returned 1 exit status
它运行,但是当我尝试重建任何更改时,我收到了该消息。我知道这意味着什么,但我不确定如何解决它。我没有删除任何源文件。我使用的是最新版本的Eclipse Mars.2
主要
//Contact list playing with classes
//Contact lists
#include "ContactList.H"
using namespace std;
int main()
{
ContactList* cl1 = new ContactList();
string name;
while(true)
{
cout << "Enter the name of the contact or q to quit." << endl;
cin >> name;
if(name == "q")
{
break;
}
cl1->insert(name);
}
cl1->printList();
return(0);
}
类
//contact list class
#include "ContactList.H"
using namespace std;
ContactList::ContactList():head(0), size(0)
{}
void ContactList::addToHead(const string& name)
{
Contact* newOne = new Contact(name);
if(head == 0)
{
head = newOne;
}
else
{
newOne->next = head;
head = newOne;
}
size++;
}
void ContactList::printList()
{
Contact* tp = head;
while(tp != 0)
{
cout << *tp << endl;
tp = tp->next;
}
}
void ContactList::insert(const string& name)
{
Contact* newNode = new Contact(name);
// case 1 - empty list
if(head == 0)
{
//assigns new node to the empty list head node
head = newNode;
}
else
{
//current pointer initialized to the head so as to start traversal
// trail pointer initialized to zero, but will iterate one step behind
// current to keep former data location on the stack organized
Contact* curr = head;
Contact* trail = 0;
// Traverse list to find insert location
while(curr != 0)
{
if(curr->name >= newNode->name)
{
break;
}
else
{
trail = curr;
curr = curr->next;
}
}
// case 2 - insert at head (not empty)
if(curr == head)
{
newNode->next = head;
head = newNode;
}
else
{
// case 3 - insert after the head (not empty)
newNode->next = curr;
trail->next = newNode;
}
}
size++;
}
答案 0 :(得分:1)
到目前为止,您的列表似乎工作正常。但请注意,调用addToHead
会破坏排序。当然,您没有这样做,但是您提供了一个能够破坏列表的预期功能的接口(正在进行排序)。最好完全放弃它。
您最常遇到的问题是operator>=
区分大小写,因此"Zebra"
<\ n> 大于或等于"ant"
({{ 1}})因此if(curr->name >= newNode->name) break;
将被排在"ant"
之后,因为ascii'Z'(90)小于ascii'a'(97)。
您可以提供我们自己的运算符(必须至少在"Zebra"
定义之前声明):
insert
这很有用,幸运的是,std :: string的运算符实际上是模板,因此该运算符在重载决策中具有优先权。
只是旁注:这绝对适用于ascii,如果使用单字节编码,适用于大多数语言。但是,有些问题与e。 G。土耳其语,如果使用utf-8,你可能会遇到问题。可能现在超出范围,但你可能记得将来......
我个人倾向于认为“Alpha”大于“alpha”,“bEta”大于“beTA”,...(与ascii代码相反!) - 但实际上,只是品味问题。不过,您可以通过将bool operator>=(std::string const& x, std::string const& y)
{
std::string::iterator ix = x.begin();
std::string::iterator iy = y.begin();
while(ix != x.end() && iy != y.end())
{
if(toupper(*ix) > toupper(*iy))
return true;
if(toupper(*ix) < toupper(*iy))
return false;
}
// both strings are equal so far...
// at least one string is at its end
//
// if iy is, then y is not longer than x and thus
// lexicographically not larger than x (so x is larger or equal)
return iy == y.end();
}
替换为:
return iy == y.end();