我需要一个关联容器,它让我通过一个字符串索引一个特定的对象,但这也保持了插入的顺序,所以我可以通过它的名字查找一个特定的对象,或者只是迭代它并按照我插入的相同顺序检索对象他们.
我认为链接列表和哈希映射的这种混合应该可以完成这项工作,但在我尝试使用之前std::tr1::unordered_map认为它以我所描述的方式工作之前,但事实并非如此.那么有人可以解释一下我的意思和行为unordered_map吗?
@wesc:我确定std :: map是由STL实现的,而我确定std :: hash_map不在STL中(我认为旧版本的Visual Studio将它放在名为stdext的命名空间中).
@cristopher:所以,如果我做对了,差异在于实现(以及性能),而不是它在外部的行为方式.
我正在尝试使用tr1 :: unordered_map,并偶然发现了如何有效删除元素的问题.'erase'方法提供了通过键或迭代器删除.我认为后者更有效率,因为前者可能涉及隐式查找操作.另一方面,我在互联网上的调查显示,调用insert()方法后迭代器可能会变得无效.
我对典型的现实世界情况感兴趣,其中放入哈希表的对象具有足够长的寿命,以便在该寿命期间发生对insert()的调用.因此,我可以得出结论,在这种情况下,按键删除是唯一的选择吗?有没有其他选择如何更有效地删除对象?我完全清楚这个问题只在应用程序中很重要,因为删除操作经常发生.对于我当前的项目是否会出现这种情况还有待观察,但我宁愿在设计项目时了解这些问题,而不是已经存在大量代码.
编辑:解决了,我知道如何,但我不明白为什么.
我改变了variables声明
tr1::unordered_map<int,T> variables;
Run Code Online (Sandbox Code Playgroud)
至
unordered_map<int,T> variables;
Run Code Online (Sandbox Code Playgroud)
它工作正常.
如果你知道为什么请在答案中写下来.
我有一个非常大的程序,所以我不知道我应该带哪个代码.
有一个抽象类,它继承了派生类.摘要有unordered_map<int,int>(模板)作为私有成员和公共方法insert(int,int).
派生类使用基类insert方法将元素插入unordered_map<int,int>容器,
第一个int使用像计数器一样,从0开始.前十一个插入元素正常,但在第12个元素中我得到sigsegv,而struct equal_to在stl_function.h中错误(209).
在调试器中,我看到unordered_map的bucket_count等于11,也许它是某些东西的线索.
我的编译器是gcc 4.6.1.
也许你可以写一般可以导致sigsegv的内容unordered_map.insert?
谢谢,抱歉我的英语不好.
如果我知道哪个,我会带来具体的代码.
编辑:这是insert方法:
virtual void Insert(int arrayPlace, T value)
{
if (!isReadOnly)
{
if (IsValueDataValid(value))
{
variables[arrayPlace] = value;
}
else
{
throw 2;
}
}
else
{
throw 4;
}
};
Run Code Online (Sandbox Code Playgroud)
声明是:
tr1::unordered_map<int,T> variables;
Run Code Online (Sandbox Code Playgroud)
当arrayPlace== 11时,sigsegv会发生,并且无关紧要value.
换句话说,如果我填充两个unordered_map或者unordered_set具有完全相同内容和相同散列函数的对象,那么迭代它们会给出相同的键/值对序列吗?
如果是这样,那么它的条件是什么(例如相同的散列函数,相同的键,不一定是相同的值).
这是我正在运行的代码,使用g ++ 4.6和 -std=c++0x
std::unordered_map<int, int> um;
um.insert(std::make_pair(42, 43));
um.insert(std::make_pair(342, 343));
um.insert(std::make_pair(142, 143));
um.insert(std::make_pair(242, 243));
for(auto e : um)
std::cout << e.first << std::endl;
Run Code Online (Sandbox Code Playgroud)
这打印:
242
342
42
142
Run Code Online (Sandbox Code Playgroud)
现在我可以用um.begin()->first或访问242 um.begin(0)->first.342可以使用um.begin(1)->first.但是um.begin(2)->first或者um.begin(3)->first使程序崩溃.我能够访问不同的数字um.begin(2)->first.我无法向自己解释这种行为.我用um.begin(int)错了吗?
可能这很容易,但我只是想了解我们是否可以这样做:
假设我们有一个unordered_map(string, string)默认情况下,如果两个字符串相等,它将检查相等性.
现在,假设我们在相等运算符中再添加一个函数,即使两个字符串是彼此的字符串,也会返回true.为此,我们是否只能更新相等运算符而不是hasher(并使用默认的hasher).
例如,仅定义仿函数:
bool operator() (const string& a, const string& b) const
{
// check for anagram condition here
}
Run Code Online (Sandbox Code Playgroud) 我不明白为什么我的编译器不接受下面的代码
#include <unordered_set>
#include <unordered_map>
template<class T>
using M = std::unordered_set<T>;
template<class T>
using D = M<T>;
template<class T>
using DM = std::unordered_map < typename M<T>::const_iterator // Problem
, typename D<T>::const_iterator >; // Problem
int main(int argc, char ** argv)
{
D<int> d;
M<int> m;
DM<int> dm; // Problem
}
Run Code Online (Sandbox Code Playgroud)
编译器命令是
clang++ -std=c++14 test.cpp -o test
Run Code Online (Sandbox Code Playgroud)
编译器错误消息摘录是
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/bits/hashtable_policy.h:85:11: error:
implicit instantiation of undefined template
'std::hash<std::__detail::_Node_const_iterator<int, true, false> >'
noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
Run Code Online (Sandbox Code Playgroud)
为什么不允许使用它typename M<T>::const_iterator作为键std::unordered_map?
我写了一个小程序,用两个样本数据创建了两百万张地图的向量,然后查询一些值。
我知道我可以在此时使用数据库,但是我只是在四处探索以实现性能优化。
代码:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <map>
#include <string>
#include <chrono>
using namespace std;
static int NUM_OF_MAPS = 2 * 1000 * 1000;
void buildVector(vector<unordered_map <string, int>> &maps);
void find(string key, int value, vector<unordered_map <string, int>> &maps);
int main() {
auto startPrg = chrono::steady_clock::now();
vector<unordered_map <string, int>> maps;
buildVector(maps);
for (int i = 0; i < 10; i++) {
string s(1, 'a'+ i);
find(s, i, maps);
}
auto endPrg = chrono::steady_clock::now();
cout << "program duration: " …Run Code Online (Sandbox Code Playgroud) 该代码段似乎不起作用,因为唯一指针被存储到pair对象中,然后试图从其中复制。可以避免吗?
std::unordered_map<std::string,std::unique_ptr<int>> _map {
{"hello", std::make_unique<int>(7)}
};
Run Code Online (Sandbox Code Playgroud)
完整的代码示例和编译错误可以在这里查看http://cpp.sh/7uc3a
我正在尝试std::unordered_map使用构造函数初始化一个构造函数,该构造函数通过初始化列表和初始存储桶数量接受数据。
出于某种原因,如果将其放入main,则该构造函数会起作用,但是将其放入类标头时会出现语法错误。
具体来说,标题为momo.h:
#pragma once
#include <unordered_map>
namespace std
{
template <>
struct hash<std::pair<uint16_t, uint16_t>>
{
std::size_t operator()(const std::pair<uint16_t, uint16_t>& k) const
{
return (std::hash<long>()((((long)k.first) << 16) + (long)k.second));
}
};
}
class test
{
std::unordered_map<std::pair<uint16_t, uint16_t>, uint16_t> m_Z(
{ /* Fails here: syntax error: missing ')' before '{' */
{std::pair{ 1, 2 }, 3},
{std::pair{ 4, 5 }, 6}
}, 128);
};
Run Code Online (Sandbox Code Playgroud)
而如果我将标头中的定义删除为main:
#include "Momo.h"
int main()
{
test X;
std::unordered_map<std::pair<uint16_t, …Run Code Online (Sandbox Code Playgroud) c++ ×10
unordered-map ×10
c++11 ×5
c ×1
c++14 ×1
constructor ×1
dictionary ×1
erase ×1
performance ×1
stl ×1
templates ×1
tr1 ×1
unique-ptr ×1
vector ×1