确定STL映射是否包含给定键的值的最佳方法是什么?
#include <map>
using namespace std;
struct Bar
{
int i;
};
int main()
{
map<int, Bar> m;
Bar b = {0};
Bar b1 = {1};
m[0] = b;
m[1] = b1;
//Bar b2 = m[2];
map<int, Bar>::iterator iter = m.find(2);
Bar b3 = iter->second;
}
Run Code Online (Sandbox Code Playgroud)
在调试器中检查它,它看起来就像iter垃圾数据.
如果我取消注释这一行:
Bar b2 = m[2]
Run Code Online (Sandbox Code Playgroud)
调试器显示的b2是{i = 0}.(我猜这意味着使用未定义的索引会返回一个包含所有空/未初始化值的结构?)
这些方法都不是很好.我真正喜欢的是这样的界面:
bool getValue(int key, Bar& out)
{
if (map contains value for key)
{
out = map[key];
return true; …Run Code Online (Sandbox Code Playgroud) 我发现检查重复项的唯一方法是插入并检查std::pair.secondfor false,但问题是如果密钥未使用,这仍会插入一些东西,而我想要的是一个map.contains(key);函数.
哈希表可以实现O(1)似乎是常识,但这对我来说从来没有意义.有人可以解释一下吗?以下是两种情况:
答: 该值是一个小于哈希表大小的int.因此,该值是它自己的哈希值,因此没有哈希表.但如果有,那将是O(1)并且仍然是低效的.
B. 您必须计算值的哈希值.在这种情况下,查找数据大小的顺序为O(n).在你做O(n)工作之后,查找可能是O(1),但在我眼中仍然是O(n).
除非你有一个完美的哈希表或一个大的哈希表,否则每个桶可能有几个项目.因此,无论如何,它在某个时刻转变为一个小的线性搜索.
我认为哈希表很棒,但我没有得到O(1)的名称,除非它只是理论上的.
维基百科关于哈希表的文章始终引用常量查找时间并完全忽略哈希函数的成本.这真是一个公平的衡量标准吗?
编辑:总结我学到的东西:
这在技术上是正确的,因为哈希函数不需要使用密钥中的所有信息,因此可以是恒定时间,并且因为足够大的表可以将冲突降低到接近恒定的时间.
在实践中确实如此,因为随着时间的推移,只要选择散列函数和表大小来最小化冲突,即使这通常意味着不使用常量时间散列函数,它也只会有效.
我的用例:
map<string, Car> cars;
bool exists(const string& name) {
// somehow I should find whether my MAP has a car
// with the name provided
return false;
}
Run Code Online (Sandbox Code Playgroud)
能否请您用C++建议最好和最优雅的方式?谢谢.
我已经在stackoverflow上阅读了关于web和问题的不同文章,但对我来说,目前尚不清楚是否有更好的std::map::at用于检索map元素的情况.
根据定义,std::map::at
返回对使用键k标识的元素的映射值的引用.
如果k与容器中任何元素的键不匹配,则该函数抛出out_of_range异常.
仅限于我std::map::at在100%确定存在具有特定键的元素时值得使用的情况,否则您应该考虑异常处理.
std::map::at被认为是最有效和优雅的方式?在什么情况下你会建议使用std::map::at?map::find()当有可能没有带有这样一个键的元素时,最好使用它吗?并且map::find()它更快,更好的方法?Run Code Online (Sandbox Code Playgroud)if ( map.find("key") != map.end() ) { // found } else { // not found }
PS
map::operator[] 有时可能很危险,因为如果一个元素不存在,那么它会插入它.
在我的函数中,我有这个参数:
map<string,int> *&itemList
Run Code Online (Sandbox Code Playgroud)
我想先检查是否存在密钥.如果此键存在,则获取该值.我想这个:
map<string,int>::const_iterator it = itemList->find(buf.c_str());
if(it!=itemList->end())
//how can I get the value corresponding to the key?
Run Code Online (Sandbox Code Playgroud)
检查密钥是否存在的正确方法是什么?
我有两个stl地图map<int,int> ,我想比较它们..所以这里是代码..
map <int, int> a,b;
insert into a and b;
map<int,int>::iterator i;
for(i=a.begin();i!=a.end();i++){
if(what should be here?)
then cout << (*i).first << " also present in b" << endl;
}
Run Code Online (Sandbox Code Playgroud)
我希望像(b [(*i).first])之类的东西存在?
我有以下结构:
std::map<int, std::map<int, int>> my_map;
Run Code Online (Sandbox Code Playgroud)
我想检查密钥是否my_map[3][5]存在。
除了以下方法之外,还有更简单/更短的方法吗?
if (my_map.find(3) != my_map.end()) {
std::map<int, int>& internal_map = my_map[3];
if (internal_map.find(5) != internal_map.end()) {
// ... Do something ...
}
}
Run Code Online (Sandbox Code Playgroud) 我在某些情况下使用以下代码:
#define array_key_exists(find_key, arr) (arr.find(find_key) != arr.end())
Run Code Online (Sandbox Code Playgroud)
但我也只使用这种方法:
if(SomeMap["something"]){
// key exists
}
Run Code Online (Sandbox Code Playgroud)
我正在使用String to int map.
它们都快吗......?或者假设我没有在地图值中使用零值,第二种情况是否有可能出现错误?到目前为止,第二种情况似乎工作正常.
在C++中,如何检查是否存在带键的元素?