【问题标题】:How can I fill a map of int and vector<int> in C++?如何在 C++ 中填充 int 和 vector<int> 的映射?
【发布时间】:2013-02-18 00:12:11
【问题描述】:

我一直在使用&lt;map&gt;,我在其中声明了一张地图,如下所示:

map <int, vector<int> > tree;

我现在正在尝试为它分配值。我的目标是将多个值作为其键的元素。像这样的:

0=null
1=>0
2=>1,0
3=>2,1,0
4=>3,2,1,0
5=>0

我尝试这样分配给地图,但它不起作用:

tree[3]=vector<int>(2,1,0);

但是,以下两种分配工作的方式:

tree[1]=vector<int>(0);
tree[2]=vector<int>(1,0);

问题出在哪里?如何制作一个可以用作 Python 字典的函数?

我没有使用 C++11。

【问题讨论】:

  • 这不是一个有效的 std::vector 构造函数调用。
  • 在您的场景中向量中整数的顺序是否重要?
  • 呃...请检查值。 vector&lt;int&gt;(0) 生成一个 empty 向量,vector&lt;int&gt;(1,0) 生成一个具有单个元素的向量 0。对于std::vector,请参阅constructors

标签: c++ dictionary vector containers stdmap


【解决方案1】:

使用 C++11,您可以尝试:

tree[3]=vector<int>({2,1,0});

除此之外,这个问题可以使用更多细节和一些你已经尝试过的代码......

【讨论】:

  • 返回这个错误:error: deducing from brace-enclosed initializer list requires #include &lt;initializer_list&gt; view.cc:578: error: no matching function for call to ‘std::vector&lt;int, std::allocator&lt;int&gt; &gt;::vector(&lt;brace-enclosed initializer list&gt;)’
  • 你的意思是#include &lt;vector&gt; 吗?
  • 没有。我的意思是#include &lt;initializer_list&gt;。您阅读编译器为您生成的错误消息了吗?
  • 实际上没有必要明确说明类型。在分配的 RHS 上,纯大括号初始化列表也应该工作:tree[3] = { 2 , 1 , 0};
【解决方案2】:

由于您要求 C++03 的答案,这个(比 C++11 更详细)解决方案将起作用。

tree[3].push_back(2);
tree[3].push_back(1);
tree[3].push_back(0);

【讨论】:

    【解决方案3】:

    请注意,以下两行并没有达到您的预期:

    tree[1] = vector<int>(0);
    tree[2] = vector<int>(1, 0);
    

    对应vector's constructor的第一个参数是容器的初始大小。第二个参数是初始化容器元素的值。因此,第一行构造了一个空向量,第二行构造了一个向量,其中一个元素初始化为 0。

    如其他答案所示,如果您不能使用C++11 featurespush_back() 是一个不错的选择。但是,一旦升级到 C++11,您还可以使用嵌套的 list initialization 来初始化您的地图,如下所示:

    int main() {
        std::map<int, std::vector<int>> tree{
            {1, {0}}, {2, {1, 0}}, {3, {2, 1, 0}}, {4, { 3, 2, 1, 0 }}, {5, { 0 }}
        };
    
        for (auto const &kv : tree) {
            std::cout << kv.first << " =>";
            for (auto const &i : kv.second)
                std::cout << " " << i;
            std::cout << std::endl;
        }
    
        return 0;
    }
    

    输出:

    1 => 0
    2 => 1 0
    3 => 2 1 0
    4 => 3 2 1 0
    5 => 0

    Code on Ideone

    【讨论】:

      【解决方案4】:

      你考虑过std::multi_map吗?

      #include <map>
      
      int main()
      {
          std::multimap<int, int> map;
      
          for (int i=1; i < 6; i++)
              for (int j=1; j < i; j++)
                  map.insert(std::make_pair(i, j));
      }
      

      【讨论】:

        【解决方案5】:

        正如 Daniel Frey 指出的那样,您可以使用

        tree[3] = vector<int>({2,1,0})
        

        在类似python的伪代码中,这里使用的向量构造函数是

        def vector(arr)
        

        原始帖子建议您尝试使用表单的构造函数

        def vector(*args)
        

        不存在的。

        如果您不使用 C++11,请考虑使用vectorother constructors 之一。

        【讨论】:

          【解决方案6】:

          没有 C++11,代码不会那么优雅:

          tree[0]; // create empty vector for index 0
          tree[1].push_back(0);
          tree[2].push_back(1);
          tree[2].push_back(0);
          tree[3].push_back(2);
          tree[3].push_back(1);
          tree[3].push_back(0);
          tree[4].push_back(3);
          tree[4].push_back(2);
          tree[4].push_back(1);
          tree[4].push_back(0);
          tree[5].push_back(0);
          

          【讨论】:

          • 您有什么理由将此信息放在单独的答案中?
          • 将 C++11 与 C++03 分开。在这种情况下我不应该这样做吗?
          • 嗯。我永远不会这样做,因为 1) 很容易使用 Markdown 来构建一个稍长的答案,以便轻松地将 C++03 和 C++11 部分分开,以及 2) 给出两个答案会让它看起来像你只想要双倍的声望。但我相信没有明确的政策。 herehere 上有元帖子。
          • 好的,明白了。我认为它会更清楚,因为“没有 C++11”的信息只是稍后给出的。但是现在我不能删除这个答案,所以请忽略它,我不会再这样做了。我很久以前创建了我的帐户并忘记了它,我才三周前才开始使用它,所以我在这里仍然觉得自己像个菜鸟:)
          【解决方案7】:

          我不是特别喜欢 va_args,但只要您(用户)不搞砸,即混合类型,解决方案在一定程度上比大多数解决方案“更整洁”。另一个缺点是您的向量不能包含 -1,但您的示例案例没有显示它。

          #include <vector>
          #include <cstdarg>
          #include <iostream>
          
          //Unsafe but it works.
          template<typename T>
          std::vector<T> make_vector(T num, ...) {
              std::vector<T> result;
              va_list args;
              va_start(args,num);
              for(T i = num; i != -1; i = va_arg(args,T))
                  result.push_back(i);
              va_end(args);
              return result;
          }
          
          int main() {
              std::vector<int> v = make_vector(0,1,2,3,-1); //-1 to stop
              //do stuff with vector v
          }
          

          【讨论】:

          • boost 没有使用逗号填充向量的功能吗?
          猜你喜欢
          • 2022-11-04
          • 2010-09-27
          • 1970-01-01
          • 1970-01-01
          • 2022-08-07
          • 1970-01-01
          • 2015-08-27
          • 2018-03-07
          • 1970-01-01
          相关资源
          最近更新 更多