检查映射中是否存在关键字,然后更新值

checking if key exist in map then updating value

本文关键字:然后 更新 关键字 存在 映射 是否 检查      更新时间:2023-10-16

在我的项目中,我想插入映射的键。所有新关键点的值都应为1.0,但现有关键点应增加1。

这是代码

vector <string> pairs; 
map<string, float> two;
map <string, float>::iterator it;
string a = "a";
string b = "b";
string c = "a";
pairs.push_back(a);
pairs.push_back(b);
pairs.push_back(c);
for(int i=0; i<pairs.size(); i++)
{
    it = two.find(string(pairs[i]) );
    if(i==0)
    {
        two[string(pairs[i])]=1.0;
    }
    else if ( it == two.end() ) 
    {
        it->second = it->second + 1.0;
    //after this line ^,my compiler stop working
    }
    else
    {
        two[string(pairs[i])]=1.0;
    }
}

之后,对象应该是

a  2
b  1

我该怎么做。

最简单、最高效的解决方案是:

for (auto const& s :  pairs) two[s] += 1.0;

这是因为如果键不存在,映射上的[]运算符会使用默认值构造函数自动创建一个条目。对于浮点,默认构造函数生成0.0。

由于[]返回一个引用,因此不会执行任何额外的查找来增加值。

else if ( it == two.end() ) 
    {
        it->second = it->second + 1.0;

以上代码行需要按照以下进行更正

else if ( it != two.end() ) 
             ^^^
    {
        it->second = it->second + 1.0;

不止于此:

it = two.find(string(pairs[i]) );

上面的行可以重写如下

it = two.find(pairs[i] );

STL的设计就是为了高效地做到这一点,看看如何做到这一步是值得的。

但首先,请注意,在您的代码中,行

two.find(string(pairs[i]) );
two[string(pairs[i])]=1.0;

执行两次查找,这有点浪费。

如果查看map::insert的签名,可以看到返回值是std::pair<iterator, bool>。第二个是布尔值,指示元素是否实际插入。第一个是前一个元素(如果它存在,在这种情况下它没有被覆盖(或新元素的迭代器。

因此,有效地做到这一点的方法是编写

auto ins = two.insert(make_pair(pairs[i], 0));
ins.first->second += 1;

应该有它!=two.end((而不是it==two.end

我认为第一个条件(I==0(检查也可以跳过