除了find_if()或迭代器之外,还可以通过键访问对向量中的元素

时间:2018-06-10 06:48:03

标签: c++ c++11 lookup stdvector std-pair

所以我有一个对的向量,其中包含另一个像这样编写的对向量(与2D向量相同,但'int'有点像元素的键):

struct Item
{
    string word = "";
    int count[3] = {0, 0, 0};
};

vector< pair<int, vector< pair<int, Item> > > > MyWords;

目前,给定两个整数键我访问唯一元素的方式如下:

//Find the pair with a key == key1 in the main vector
auto it1 = find_if(MyWords.begin(), MyWords.end(), 
           [](const pair<int, vector<pair<int, Item> > >& element){
               return element.first == key1;
           });

//Find the pair with a key == key2 in the vector that has a key == key1
auto it2 = find_if(it1 -> second.begin(), it1 -> second.end(),
           [](const pair<int, Item>& element){
               return element.first == key2;
           });

//Access the element using the returned iterator
it2 -> second.count[0] = A_Number_Here;

我正在尝试找到一种更好的方法来访问元素,比如像索引一样使用键(键从0开始)。不幸的是,使用[]会导致分段错误:

MyWords[key1].second[key2].second.count[0] = A_Number_Here;

还有其他想法吗?我知道还有其他STL容器,如地图和集合,但我目前正在尝试使用矢量。

顺便说一下,我还想问一下find_if()的时间复杂度是什么?

编辑:对的键可能不是连续的(0,1,2,3 ...)

1 个答案:

答案 0 :(得分:2)

  

我尝试使用像索引这样的键来访问元素。   不幸的是,我总是收到分段错误。

MyWords[key1].second[key2].second.count[0] = A_Number_Here;
     

还有其他想法吗?

首先,它做这样的矢量数据结构很繁琐。您应该重新考虑数据结构要求,并应该提出更轻松的东西。其次,您的访问方式中存在没有错误。这是正确的。的 SEE THIS

可能您提供了错误的密钥(key1key2)来访问矢量内容。需要注意的一点是,由于std::vector不是std::map,因此您引入的密钥对将无法正常工作。

当您执行MyWords[key1]. and rest.....,例如Key1 = 0时,您正在访问向量MyWords的第一个元素,其中第一个int可以是任何值。(不一定是0,正如你所提到的,你有一个未分类的向量)。我认为你假设发生了这种情况并尝试了一些大于MyWords.size()的值。

问题的解决方案是使用 iterator based looping/ accessing ,这只会显示你所拥有的内容或坚持使用std::find_if,因为它会返回矢量迭代器,以防在内部找不到密钥。

#include <iostream>
#include <vector>
#include <algorithm>

struct Item
{
   std::string word;
   std::vector<int> count; // changed to vector array
};
using Pair = std::pair<int, std::vector< std::pair<int, Item> > >;

int main()
{
   std::vector< Pair > MyWords =
   {  //int, <std::pair<int,          Item            > > >
      {1   , {        {    4,  Item{"String1", {1,2,3}} } }       },
      {0   , {        {    5,  Item{"String2", {5,2,8}} } }       },
      {2   , {        {    8,  Item{"String3", {1,7,9}} }, {    9,  Item{"String4", {11,77,99}} } }       }
   };

   for(const auto& bigPair: MyWords)
   {
      std::cout << "Key : " << bigPair.first;

      for(const auto& smallPair: bigPair.second)
      {
         std::cout << "\nValues: " << smallPair.first << "\t";

         std::cout << smallPair.second.word << " "
                  << smallPair.second.count[0] << " "
                  << smallPair.second.count[1] << " "
                  << smallPair.second.count[2] ;
      }
      std::cout << "\n\n";
   }

   return 0;
}
  

我还想问一下find_if()的时间复杂度是什么?

std::find_if根据first您的lastpredicate迭代器之间的距离可能会有时间复杂度,高达线性提供,它将搜索每个元素,直到找到匹配项。

作为alter native,您可以将std::lower_bound与自定义lambda /谓词一起使用(仅在找到匹配时返回,否则它还将返回指向 next greater 元素的迭代器根据第一个值(键)排序 MyWords向量后,向量(如果可用)std::lower_bound只有 O(longn)的时间复杂度,这比std::find_if要快得多。