我的问题:我想使用std::stack<std::pair<int,int>, std::unordered_set<std::pair<int,int>>
或std::stack<coords, std::unordered_set<coords>>
简称
我想知道是否可以扩展std::unordered_set<>
,使其在std::stack<>
内无任何问题。
除此之外,我想知道它是否值得付出努力,而不泄露实际的最终用途。我只是意味着使用unordered_set的好处是使用必要的方法设计我自己的模板更有效,而不是扩展现有的unordered_set以满足要求?
编辑:通常我会删除一个否定的问题,但我觉得这可能最终会对其他一些误解了std :: unordered_set的可怜的灵魂有所帮助。然后我还没死,所以我可能会删除它。
编辑2:来自AndreyT的答案有助于弄清楚为什么std::stack<std::pair<int,int>, std::unordered_set<std::pair<int,int>>
不能成为一件事。我切换到jxh的答案,因为它基本上实现了一个,并且接近我最终使用的。
答案 0 :(得分:5)
正如在不同的答案中已经解释的那样,无序集合不是堆栈接口的合适容器,因为提供的容器应该提供排序语义。无序集不提供排序语义,如其名称所示。
看起来你想要的是一个LIFO数据结构,但是你希望能够在O(1)中找到该数据结构中的特定元素,并对其进行操作(我想找到并删除它)。
你可以做的最好的事情就是你自己的数据结构,它有一个使用列表的堆栈,以及一个无序的坐标映射到该列表中的迭代器。
class MyFunkyStack {
std::list<coord> list_;
std::stack<coord, std::list<coord>> stack_;
std::unordered_map<coord, std::list<coord>::iterator> map_;
//...
MyFunkyStack () : list_(), stack_(list_), map_() {}
coord top () const { return stack_.top(); }
void push (coord c) {
stack_.push(c);
map_[c] = list_.end() - 1;
}
void pop () { erase(top()); }
void erase (coord c) {
std::unordered_map<coord, std::list<coord>::iterator>::iterator i;
if ((i = map_.find(c)) == map_.end()) return;
list_.erase(i->second);
map_.erase(i);
}
//...
};
向B-52道歉:
<子>
如果您看到存档的系统日志中隐藏的旧日志行显示:/
“哈希堆栈中的15 MB”/
Hash Stack,是的,是的//
我正在下载一个开源项目。 /
寻找hash-ay能力! /
今天编译哈希表。 //
我给了我一个tar-ball,它对于电子邮件来说太大了。 /
我们正在为我的Hash Stack下载它。 //
我给了我一个编译器,它优化了很多,/
快点,准备你的构建盒! //
Hash Stack是我们一起制作的一个奇怪的容器。 /
哈希堆栈,宝贝(哈希堆栈宝贝!)//
哈希堆栈,宝贝,哈希堆栈! /
哈希堆栈,宝贝,哈希堆栈! //
(哈希,宝贝,这就是它所在的地方。)/
(哈希,宝贝,这就是它所在的地方。)//
许可证(哦!)是开源的家伙! /
导致哈希堆栈的共享变得很酷。 //
这只是一个小班,只有几个领域。 /
这是一个奇怪的时髦堆栈,有点像黑客。 //
不需要析构函数。 /
不需要分配。 /
不需要移动或复制。 /
不需要分配。 //
Hash Stack是我们一起制作的一个奇怪的容器。 /
哈希堆栈,宝贝(哈希堆栈宝贝!)//
(哈希,宝贝,这就是它所在的地方。)/
(哈希,宝贝,这就是它所在的地方。)//
打字和鼠标,/
思考和编码,/
几乎没穿,/
因为我在家工作(是的)。 //
哈希堆栈编译! /
哈希堆栈编译! //
哈希堆栈编译,/
而其他堆栈仍然只是/
数组,数组,数组和数组! //
其他堆栈只是推动,其他堆栈刚刚弹出,宝贝! /
排队的最后排队是第一批排队的人。 //
其他堆栈只是推动,其他堆栈刚刚弹出,宝贝! /
一个奇怪的时髦堆栈! /
一个奇怪的时髦堆栈! //
当我编译(依赖是陈旧的)时,我发送电子邮件! //
我发布了一个新的“制造”,租给-20,/
快点,准备你的构建盒! //
Hash Stack是我们一起制作的一个奇怪的容器。 /
哈希堆栈,宝贝(哈希堆栈宝贝!)//
哈希堆栈,宝贝,哈希堆栈! /
哈希堆栈,宝贝,哈希堆栈! //
(哈希,宝贝,这就是它所在的地方,是的。)/
(哈希,宝贝,这就是它所在的地方。)//
测试,测试,测试,仍然没有核心,宝贝。 /
再尝试几个案例,宝贝/
测试,测试,测试,仍然没有核心,宝贝。 /
你的测试计划是什么? //
测试,测试,测试,仍然没有核心,宝贝。 /
再试几个案例,糖/
测试,测试,测试,仍然没有核心,宝贝。 /
你的测试计划是什么? //
测试,测试,测试,仍然没有核心,宝贝。 /
(再试几个案例。)/
测试,测试,测试,仍然没有核心,宝贝。 //
测试一下! (有个核心,宝贝!)/
测试一下! (有核心!)/
测试一下! (有个核心,宝贝!)/
测试一下! //
你做了什么? /
转载,封锁! //
哈希堆栈,宝贝,哈希堆栈! /
(哈希,宝贝,这就是它所在的地方,是的。)/
(哈希,宝贝,这就是它所在的地方。)//
哈希,宝贝,哈希堆栈! /
打字和鼠标,/
思考和编码,/
在哈希堆栈上。
子>
答案 1 :(得分:4)
std::stack
意图是根据LIFO原则排序的数据结构。在该意图中,它以特定顺序将数据放入底层容器中,并期望该容器维护该顺序。不可能将任何能够自行改变排序的容器用作底层容器。消除了任何无序数据结构或按照其他原则排序的数据结构。
但是,该逻辑仅适用于您希望保持std::stack
的上述意图,即按字面意思使用它来实现堆栈。
如果你不关心你到底得到了什么(在最极端的情况下,如果你只是想让你的代码“编译”),那么你可以看到std::stack
是一个“瘦”的抽象接口适配器只做适应某些底层类的接口。从这个角度来看,只要满足所需的接口规范,就可以将任何东西用作底层“容器”。据我记忆,这包括empty
,size
,back
,push_back
,pop_back
方法的可用性以及可能的某些typedef。
unordered_set
不满足所需的接口规范。你可以正式“扩展”它只是“使它编译”,但我不知道你怎么可能使它适用于真正的堆栈。