首先,我无法在互联网上找到关于铃声数据结构的更多信息,所以这里是一个简短的实现,显示一个响铃是什么(根据我的讲师)
template<typename Key, typename Info>
class Ring
{
struct Node // structure for storing the data
{
Key k;
Info inf;
Node* next;
Node* prev;
};
Node* any; // pointer to a node belonging to the ring, NULL if the ring is empty
};
它类似于循环列表,但any
可以指向结构中的任何元素,我们不关心顺序,我们添加的位置等。
除了我已经完成的项目的主要任务之外,我们必须以这样的方式实现迭代器,
for(auto it = r1.begin(); it != r1.end(); ++it) // r1 is a ring
{ cout << *it << ' '; }
正常工作,即。打印整个戒指。
甚至可能吗?迭代器end()应指向一个地方,下一个元素将被添加,我们没有这样的观点。如果它被设置为any
(与begin()相同),则根本不会执行循环,如果它被设置为any->prev
,它将省略最后一个元素。
您有什么想法,我该如何实现?或者我是对的,这是不可能的?
答案 0 :(得分:0)
end()
在一个响铃的背景下毫无意义:你无法在一个响铃中识别出一个位置超过最后一个元素&#34;,这是什么if
是。
迭代一个环的惯用方法是从任意点向相反方向发送两个迭代器,并在两个迭代器到达后终止,其中一个具有#34;处理&#34;,相同的元素。 / p>
答案 1 :(得分:0)
对于单项铃声,如果begin()
和end()
都必须引用节点,则begin()
和end()
会明确引用相同的节点,但它们可以&# 39; t比较相等,因为这会导致循环在第一次迭代之前退出。
因此,您可以得出结论,对于这些迭代器,不能仅根据它们所引用的节点来定义相等性。
即。你只需要以合适的方式定义迭代器相等性。
在许多情况下,结束迭代器只是一个默认构造的迭代器。
所以这不是什么新鲜事。
示例:
#include <assert.h> // assert.h
#include <iterator> // std::(iterator, forward_iterator_tag)
#include <utility> // std::(pair)
namespace cppx {
class Non_copyable
{
private:
Non_copyable( Non_copyable const& ) = delete;
auto operator=( Non_copyable const& ) -> Non_copyable& = delete;
public:
auto operator=( Non_copyable&& ) {}
Non_copyable() {}
Non_copyable( Non_copyable&& ) {}
};
} // namespace cppx
namespace my {
using std::pair;
using std::iterator;
using std::forward_iterator_tag;
template< class Key, class Value >
class Ring
: public cppx::Non_copyable
{
public:
using Pair = pair<Key, Value>; // Movable
private:
struct Node // For storing the data
{
// Key key;
// Value value;
Pair kv;
Node* next;
Node* prev;
};
class Iterator
: public iterator<forward_iterator_tag, Pair>
{
private:
Node* p_first_;
Node* p_current_;
auto is_end() const -> bool { return p_first_ == nullptr; }
void advance()
{
p_current_ = p_current_->next;
if( p_current_ == p_first_ )
{
p_first_ = nullptr;
assert( is_end() );
}
}
public:
friend
auto operator==( Iterator const& a, Iterator const& b )
-> bool
{ return !!a.p_first_ == !!b.p_first_ and a.p_current_ == b.p_current_; }
friend
auto operator!=( Iterator const& a, Iterator const& b )
-> bool
{ return not( a == b ); }
auto operator++()
-> Iterator&
{
advance();
return *this;
}
auto operator++( int )
-> Iterator
{
Iterator result = *this;
advance();
return result;
}
auto operator*() const
-> Pair const&
{ return p_current_->kv; }
auto operator->() const
-> Pair const*
{ return &p_current_->kv; }
Iterator( Node* p, bool be_end = false )
: p_first_( be_end? nullptr : p )
, p_current_( p )
{}
};
Node* p_current_; // Node in the ring, 0 if the ring is empty.
public:
// TODO: add new node, before current node if any.
void add( Pair kv );
// TODO: advance n positions, backward for negative n.
void advance( int const n = 1 );
// TODO: a unique id for current position.
auto current_position() const -> void const*;
auto is_empty() const -> bool;
auto current() const -> Pair const&;
auto begin() const -> Iterator { return {p_current_}; }
auto end() const -> Iterator { return {p_current_, true}; }
Ring(): p_current_() {}
Ring( Ring&& other )
: p_current_( other.p_current_ )
{ other.p_current_ = nullptr; }
};
} // namespace my
#include <iostream>
using namespace std;
auto operator<<( ostream& stream, my::Ring<int, int>::Pair const& kv )
-> ostream&
{ return stream << "{" << kv.first << ", " << kv.second << "}"; }
auto main()
-> int
{
using Ring = my::Ring<int, int>;
Ring r;
for( int i : {3, 1, 4, 1, 5, 9, 2, 6, 5, 4} )
{
r.add( {i, i*i} );
}
// Output via explicit iteration.
auto const first = r.current_position();
do
{
if( r.current_position() != first ) { cout << ", "; }
cout << r.current();
r.advance();
} while( r.current_position() != first );
cout << "\n";
// Output via range based `for` using `begin` and `end` iterators.
int count = 0;
for( Ring::Pair const& kv : r )
{
if( count++ > 0 ) { cout << ", "; }
cout << kv;
}
cout << "\n";
}
输出:
{3, 9}, {1, 1}, {4, 16}, {1, 1}, {5, 25}, {9, 81}, {2, 4}, {6, 36}, {5, 25}, {4, 16} {3, 9}, {1, 1}, {4, 16}, {1, 1}, {5, 25}, {9, 81}, {2, 4}, {6, 36}, {5, 25}, {4, 16}