【发布时间】:2015-08-21 02:00:42
【问题描述】:
我正在创建一个在插入时排序的链表。它是一个模板类,所以类型是在运行时定义的。
问题是,我正在比较两个值以查看哪个值最大,然后我将该值放在链表中应该存在的位置。这对于任何基于数学的类型都很好用,但它不适用于字符串。它不按字母顺序排序。
这是我正在尝试正常工作的代码,因此我可以比较两个字符串并找出哪个字符串按字母顺序排在第一位(但它是一个模板,因此它也必须适用于其他类型)
对比代码在这里
while ( data > iter->_data && iter->_next != 0) {
这是完整的代码,我在下面也包含了一些来自 main() 的代码
template <typename T>
class LinkedList;
template <class TNode>
class Iterator
{
friend class LinkedList<typename TNode::value_type>;
TNode* pNode;
Iterator(TNode* _pNode) : pNode(_pNode) {}
public:
void operator++() { pNode = pNode->_next; }
void operator++(int) { pNode = pNode->_next; }
bool operator!=(Iterator<TNode> rval) { return !(pNode == rval.pNode); }
bool operator==(Iterator<TNode> rval) { return (pNode == rval.pNode); }
typename TNode::value_type operator*() { return pNode->_data; }
Iterator<TNode> operator+(int _i)
{
Iterator<TNode> iter = *this;
for (int i = 0; i < _i; ++i)
{
if (iter.pNode) //If there's something to move onto...
++iter;
else
break;
}
return iter; //Return regardless of whether its valid...
}
};
template <typename T>
class Node
{
friend class LinkedList<T>;
friend class Iterator<Node<T> >;
Node() : _next(0) {}
Node(T data) : _data(data), _next(0) {}
Node(T data, Node<T>* next) : _data(data), _next(next) {}
Node(Node<T>* next) : _next(next) {}
T _data;
Node<T>* _next;
Node<T>* _prev;
public:
typedef T value_type;
};
template <typename T>
class LinkedList
{
Node<T>* first;
int count = 0;
public:
typedef Iterator<Node<T> > iterator;
typedef T value_type;
LinkedList() : first(0) {}
~LinkedList()
{
if (first)
{
Node<T> *iter = first;
while (iter != 0)
{
Node<T>* tmp = iter;
iter = iter->_next;
delete tmp;
}
}
}
bool LinkedList<T>::operator < (LinkedList<T> rhs);
bool LinkedList<T>::operator > (LinkedList<T> rhs);
void insert(T data)
{
if (first)
{
Node<T> *iter = first;
Node<T> *preIter = first;
while ( data > iter->_data && iter->_next != 0) {
preIter = iter;
iter = iter->_next;
}
if (iter == first) {
if (data < iter->_data) {
Node<T>* holder = first;
first = new Node<T>(data);
first->_next = holder;
holder->_prev = first;
first->_prev = 0;
}
else if (iter->_next != 0) {
Node<T>* newIter = new Node<T>(data);
newIter->_next = first->_next;
first->_prev = newIter;
newIter->_prev = first;
first->_next = newIter;
}
else {
first->_next = new Node<T>(data);
first->_next->_prev = first;
}
}
else if(preIter->_next != 0) {
Node<T>* newIter = new Node<T>(data);
preIter->_next = newIter;
newIter->_next = iter;
iter->_prev = newIter;
newIter->_prev = preIter;
}
else {
iter->_next = new Node<T>(data);
iter->_next->_prev = iter->_next;
}
}
};
iterator begin() { return iterator(first); }
iterator end() { return iterator(0); }
bool erase(iterator& _iNode) //True for success, vice versa
{
/* This is rather inneffecient. Maybe a better way to do this? */
/* Even then, it's *still* more effecient than a contiguous container */
if (_iNode.pNode == first)
{
first = first->_next;
delete _iNode.pNode;
return true;
}
else
{
for (Node<T>* iter = first; iter->_next; iter = iter->_next)
{
if (iter->_next == _iNode.pNode) //Find our node.
{
iter->_next = _iNode.pNode->_next;
delete _iNode.pNode;
return true;
}
}
}
return false;
}
};
使用下面的代码,最终排序结果不等于测试。它适用于整数测试(也包括在内),但不适用于字符串测试。对于第一个 A...Z 字符串测试,我最终在开头使用所有大写字符,而完整单词测试的某些单词在第二个字符串测试的位置不正确。一般来说,它相当准确,但不完全按字母顺序排列。
我怎样才能使它按字母顺序排序?
/** Test fundamental concept by storing and retrieving 0..9 */
BOOST_AUTO_TEST_CASE(ut_concept_0_to_9) {
vector<long> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto shuffle = v;
random_shuffle(shuffle.begin(), shuffle.end());
LinkedList<long> sl;
for (auto x : shuffle)
sl.insert(x);
auto it = sl.begin();
for (auto x : v) {
BOOST_CHECK_EQUAL(*it, x);
++it;
}
}
/** Test fundamental concept by storing and retrieving A..Z */
BOOST_AUTO_TEST_CASE(ut_concept_A_to_Z) {
string s = "Hello, world!";
LinkedList<string::value_type> sl;
for (auto ch : s)
sl.insert(ch);
sort(s.begin(), s.end());
auto it = sl.begin();
for (auto ch : s) {
BOOST_CHECK_EQUAL(*it, ch);
++it;
}
}
/** Test fundamental concept by storing and retrieving strings */
BOOST_AUTO_TEST_CASE(ut_concept_strings) {
vector<string> words{ "Sunna", "Mona", "Tiw", "Woden", "Thunor", "Frige", "Saturn" };
LinkedList<string> sl;
for (auto ch : words)
sl.insert(ch);
sort(words.begin(), words.end());
auto it = sl.begin();
for (auto word : words) {
BOOST_CHECK_EQUAL(*it, word);
++it;
}
}
编辑:我的独特解决方案
我最终发现我的问题不是纯粹的字母排序问题。它实际上在我的代码中。我错过了一种情况,即我将尝试放置的对象放在最后一个对象和倒数第二个对象之间。它应该已经过了最后一个对象。这段代码将被清理,因为有很多区域需要清理,但这应该正确排序。我错了需要按字母排序。
else if (iter->_next == NULL) {
if (iter->_data < data) {
iter->_next = new Node<T>(data);
iter->_next->_prev = iter->_next;
}
else {
Node<T>* newIter = new Node<T>(data);
preIter->_next = newIter;
newIter->_next = iter;
iter->_prev = newIter;
newIter->_prev = preIter;
}
}
}
我在下面标记了答案,因为我用它来解决我的问题,它也是按字母顺序排列的答案,这是我最初的问题。因此,最初的问题得到了回答,但我发现另一个问题对我来说对我来说毫无用处,但其他人可能需要这个问题的答案。
【问题讨论】:
标签: c++ string sorting templates