【问题标题】:Initialize my std::map初始化我的 std::map
【发布时间】:2016-05-06 04:19:25
【问题描述】:

我编写了下面的代码,它使用了Map。该程序查找string 键在Map 中出现的次数。如果它只出现一次,那么该 string 键的 int 的值应该是 1,依此类推。该程序运行并产生所需的输出 - 但我觉得这纯粹是运气,因为我没有在任何地方初始化 Map。我只是在做myMap[str]++ - 这绝不保证最初的值是0。那么,我如何初始化映射,以便任何string 键的值都是0,在遇到它之前我执行myMap[str]++

#include<cstdio>
#include<string>
#include<iostream>
#include<map>

int main()
{
    int t;
    long int n;
    std::string str;
    std::map< std::string, int > myMap;
    scanf("%d", &t);

    while(t--)
    {
        scanf("%ld", &n);
        std::cin.ignore();
        while(n--)
        {
            getline(std::cin, str);
            myMap[str]++;
        }

        for(std::map< std::string, int >::iterator it=myMap.begin(); it!=myMap.end(); it++)
            printf("%s %d\n", it->first.c_str(), it->second);
        printf("\n");

        myMap.erase(myMap.begin(), myMap.end());
    }

    return 0;
}

示例输入:

2
6
03 10103538 2222 1233 6160 0142
03 10103538 2222 1233 6160 0141
30 10103538 2222 1233 6160 0141
30 10103538 2222 1233 6160 0142
30 10103538 2222 1233 6160 0141
30 10103538 2222 1233 6160 0142

5
30 10103538 2222 1233 6160 0144
30 10103538 2222 1233 6160 0142
30 10103538 2222 1233 6160 0145
30 10103538 2222 1233 6160 0146
30 10103538 2222 1233 6160 0143

示例输出:

03 10103538 2222 1233 6160 0141 1
03 10103538 2222 1233 6160 0142 1
30 10103538 2222 1233 6160 0141 2
30 10103538 2222 1233 6160 0142 2

30 10103538 2222 1233 6160 0142 1
30 10103538 2222 1233 6160 0143 1
30 10103538 2222 1233 6160 0144 1
30 10103538 2222 1233 6160 0145 1
30 10103538 2222 1233 6160 0146 1

详细问题描述可见here

谢谢!

【问题讨论】:

    标签: c++ stl initialization


    【解决方案1】:

    你说:

    这绝不保证最初的值为 0

    这是不正确的。当一个key对应的item在map中不存在时,使用operator[]函数时会初始化它的值。

    来自http://en.cppreference.com/w/cpp/container/map/operator_at

    如果执行插入,则映射值是值初始化的(类类型默认构造,否则为零初始化)并返回对它的引用。

    换句话说,

            myMap[str]++;
    

    是有效且正确的代码。

    【讨论】:

    • 所以当你说它是值初始化时,++ 是如何变成1 而不是说2++ 将先前的值增加 1 - 什么保证先前的值是 0++ 使 1)?
    • 好吧,你引用的短语 zero-initialized else 让我明白了!很酷的答案,谢谢! :)
    【解决方案2】:

    您可以使用std::map::find() 检查密钥是否已经存在。如果存在,则对 find 返回的迭代器所指向的项进行增量。否则,你写myMap[str] = 0

       while(n--)
       {
            getline(std::cin, str);
            std::map< std::string, int >::iterator it = myMap.find(str);
            if( myMap.end() != it )
                 (*it).second++;
            else
                myMap[str] = 1;
       }
    

    尽管如此,您的代码还可以,因为 int 已在您的代码中初始化。它只是不可见(std::pair&lt;string,int&gt; 是默认构造的)。

    【讨论】:

    • 对不起,这不是我的问题。我的问题是 - 为什么++ 将值增加到1,因为我还没有将它初始化为0?答案,正如 R. Sahu 指出的那样,原始数据类型在 map 中是零初始化的。不过谢谢。 :)
    • @CodingBatman 我还以为你的问题是“那么,我该如何初始化地图,以便在遇到任何字符串键之前,它的值为 0……”
    猜你喜欢
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    相关资源
    最近更新 更多