【发布时间】:2014-12-19 05:05:53
【问题描述】:
我有一个问题的解决方案,该解决方案涉及从 STL 项目列表创建项目的子列表(即子范围)。例如,我有一个整数列表,需要创建子列表,其中子列表是一个类,它代表原始列表中的一系列项目。所有范围都是不相交的,我需要对子列表执行操作(插入/删除),这些更改需要反映在原始列表中。
我想出了下面的实现,它使用 C++11。但是,我在删除子列表时遇到了麻烦。问题是子列表的 _end 迭代器指向下一个连续子列表的 _beg 指针。所以我的问题是:
- 表示这种模式的常用方法是什么?即,管理列表的子列表,其中子列表中的修改反映在原始列表中。
- 我怎样才能更正下面的代码并且仍然使用 ranged-for 成语?
在这个例子中,子列表没有做很多事情,但这只是一个例子。在原始问题中,这两个类将用于几个不同的任务。
感谢任何帮助。
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
typedef list<int> i_list;
typedef list<int>::iterator it_list;
class Sublist {
private:
string _name;
i_list* _items;
it_list _beg;
it_list _end;
public:
Sublist(string name, i_list* items, it_list beg, it_list end)
: _name(name),
_items(items),
_beg(beg),
_end(end)
{
}
it_list begin() {
return this->_beg;
}
it_list end() {
return this->_end;
}
void erase(it_list it) {
if (it == _beg) {
_beg = _items->erase(it);
}
else if (it == _end) {
_end = _items->erase(it);
_end--;
}
else {
_items->erase(it);
}
}
void print() {
cout << _name << ":" << endl;
// this for access an invalid iterator
for (auto x : *this) {
cout << "\t" << x << endl;
}
}
};
class List {
private:
i_list* items;
public:
List(int size) {
items = new i_list();
for (int i=1; i<=size; i++)
items->push_back(i*10);
}
Sublist* sl(string name, int beg, int end) {
return new Sublist( name, items,
find(items->begin(), items->end(), beg),
find(items->begin(), items->end(), end));
}
};
int main() {
List f(20);
Sublist* sl1 = f.sl("SL1", 10, 60);
Sublist* sl2 = f.sl("SL2", 60, 110);
Sublist* sl3 = f.sl("SL3", 110, 160);
Sublist* sl4 = f.sl("SL4", 160, 210);
sl1->print();
sl2->print();
sl3->print();
sl4->print();
sl2->erase( sl2->begin() );
sl2->erase( sl2->begin() );
sl2->erase( sl2->begin() );
sl2->erase( sl2->begin() );
sl2->erase( sl2->begin() );
// When uncommented the program will get stuck looping
//sl1->print();
sl2->print();
sl3->print();
sl4->print();
return 0;
}
【问题讨论】:
-
效果很好。我刚刚将 List::sl 方法中创建的 Sublist* 替换为新的 list
(begin...end) 并且它起作用了。但为什么它会起作用?我认为通过这种方式元素会被复制,并且子列表中的更改不会反映在原始列表中...... -
您在哪里检查,您的更改是否反映在原始列表中?
-
你能显示你更改的代码吗?
-
@CaptainOblivious:在最坏的情况下,这将用它的 2^N 元素幂集替换 N 元素列表,因此可能不方便
-
@JohnTortugo:你的课堂上没有必要使用
ilist* items= new ilist()。只需使用ilist items。