【问题标题】:Get index of element in C++ map获取 C++ 映射中元素的索引
【发布时间】:2013-07-25 15:28:31
【问题描述】:

我的 C++ 应用程序中有一个名为 myMapstd::map,我想使用 myMap.find(key)myMap[key] 获取一个元素。但是,我还想获取该元素在地图中的索引。

std::map<string, int> myMap;
// Populate myMap with a bunch of items...
myElement = myMap["myKey"];
// Now I need to get the index of myElement in myMap

有没有一种干净的方法可以做到这一点?

谢谢。

【问题讨论】:

  • 地图没有索引,但有一个迭代器。
  • 我不认为它真的想要你的意思,但你要求的是std::distance(std::begin(myMap), myMap.find("myKey"))
  • 我很好奇:你为什么要这样做?
  • @SZH:在我看来,实现替换密码最明显的概念是将“前”字符映射到“后”字符,这不需要索引。为什么需要一个索引?
  • 您是否考虑过使用std::map&lt;char, char&gt; 代替?

标签: c++ map indexing std


【解决方案1】:

使用

int k = distance(mymap.begin(), mymap.find(mykey));

它会给你关键元素的索引。

【讨论】:

    【解决方案2】:

    一个用例:如果您想知道当您在向量上前进时有多少项更小或相等。约束:i

    vector<int> v={1, 4, 2, 3};
    set<int> s;
    s = {1}; // 1's position is 1 (one based)
    s = {1,4}; //4's positon is 2
    s = {1, 2, 4} ;//2's position is 2
    s = {1 , 2, 3, 4}; //3's positon is 3
    

    似乎 std:distance 需要 O(n) 时间。 我可以使用 set.lower_bound() 并向后计数直到 set.begin() 来实现相同的效果。有没有人有比要求 O(n) 更好的解决方案,也许使用额外的数据结构?

    好的,再想一想,这里是针对这个特定问题存储索引(基于 1)的解决方案。但是它可能无法解决在完成的地图中获取正确项目索引的问题。

    vector<int> arr={1 , 1 , 2, 4, 2};
    multimap<int, int> track; 
    for(auto a:arr)
    {
        auto it = track.insert(make_pair(a, 1)); //first item is 1
        if(it!=track.begin())
        {
            --it;
            int prev=it->second;
            it++;
            it->second+=prev;
        }  
        cout<<a<<','<<it->second-1<<endl;     
    }
    

    【讨论】:

      【解决方案3】:

      大多数时候,当您使用索引和地图时,这通常意味着您的地图在一些插入后是固定的。如果这个假设适用于您的用例,您可以使用我的答案。

      如果您的映射已经固定(之后您不会添加/删除任何键),并且您想查找键的索引,只需创建一个从键映射到索引的新映射。

      std::map<string, int> key2index; // you can use unordered_map for it to be faster
      int i = 0;
      for (pair<K, V> entry : yourMap) {
          key2index[entry.first] = i++;
      }
      

      从这个key2index 映射中,您可以尽可能多地查询密钥。只需致电key2index['YourKey'] 即可获取您的索引。

      这种方法相对于distance 函数的好处是访问时间复杂度。它是O(1),如果您经常查询,它会非常快。

      额外部分

      如果你想做相反的事情,你想从索引中访问键,然后执行以下操作。

      创建一个数组或向量来存储整个地图的键。然后就可以通过指定索引来访问key了。

      vector<int> keys;
      for (pair<K,V> entry : yourMap) {
          keys.push_back(entry.first);
      }
      

      要访问地图的索引i,请使用yourMap[keys[i]]。这也是O(1),而且速度明显更快,因为它只使用数组/向量,而不是地图。

      【讨论】:

        【解决方案4】:

        Map 是一种键值对数据结构,内部数据以树形结构的形式存在。有上面提到的 O(n) 解决方案。 “ distance(mymap.begin(),mymap.find("198765432")) ”不会给你带来正确的答案。 根据您的要求,您必须为 O log(n) 竞争操作构建自己的分段树类型数据结构。

        【讨论】:

          【解决方案5】:

          我来这里是为了寻找这个答案,但我找到了这个 distance 函数需要 2 个迭代器并返回一个索引

          cout << distance(mymap.begin(),mymap.find("198765432"));
          

          希望这会有所帮助:D

          【讨论】:

          • 这确实是问题的答案。
          • 它没有O(N) 复杂性吗?
          • "线性。但是,如果InputIt 额外满足 RandomAccessIterator 的要求,复杂度是恒定的。"见:en.cppreference.com/w/cpp/iterator/distance
          【解决方案6】:

          好吧 - map 将键和数据保持为一对 因此您可以通过将映射的迭代器解引用为 pair 或直接提取 key 的第一个元素。

          std::map<string, int> myMap;
          std::map<string, int>::iterator it;
          
          for(it=myMap.begin();it!=myMap.end();it++)
          {
              std::cout<<it->first<<std::endl;
          }
          

          【讨论】:

            【解决方案7】:

            地图的语义不包括索引。要理解这一点,您可以注意到地图通常以树的形式实现。因此,其中的元素没有索引(尝试以自然的方式为树定义索引)。

            【讨论】:

              【解决方案8】:

              std::map 并没有真正的索引,而是有一个键/值对的迭代器。这类似于索引,因为它表示集合中的排序位置,但它不是数字。要获取键/值对的迭代器,请使用find 方法

              std::map<string, int>::iterator it = myMap.find("myKey");
              

              【讨论】:

                【解决方案9】:

                地图中没有索引之类的东西。地图不是作为“对”序列存储的(至少不是必要的;实际上在大多数实现中它们不是)。

                然而,无论实现如何,std::map 都不会对具有索引的容器进行建模。

                根据您提出这个问题的目的,“索引”可以是迭代器(如其他人所建议的那样)或键本身。

                但是,您问这个问题听起来很奇怪。如果您能给我们提供更多详细信息,我们可能会为您指出解决问题的更好方法。

                【讨论】:

                • 我认为你的第二句话编辑得太多了;与真实相反。
                • std::map 总是排序的。只是想更正答案中的陈述。
                猜你喜欢
                • 1970-01-01
                • 2012-02-26
                • 1970-01-01
                • 1970-01-01
                • 2011-12-14
                • 2023-04-09
                • 1970-01-01
                • 2012-04-09
                • 1970-01-01
                相关资源
                最近更新 更多