用向量的向量元素初始化向量的空向量

时间:2020-02-07 08:23:06

标签: c++ c++11 vector

我有一个函数,该函数将使用来自字符串类型的向量的给定向量中的某些元素来初始化字符串类型的向量的空向量。我的语法看起来像这样

std::vector<std::vector<std::string>> extract_data_on_userid(const std::vector<std::vector<std::string>> &array, std::vector<std::string> &user_ids, const int nr_of_events)
{
  std::vector<std::vector<std::string>> data_extract;
  int event_iterator = 0;
  int user_id_iterator = 0;

  // While loops which extracts the events based on user IDs
  while (event_iterator <= nr_of_events)
  {
    // While loop which finds specified user id in an event
    while (user_id_iterator < array[0].size())
    {
      if (check_id(user_ids, array[0][user_id_iterator]))
      {
        for (size_t i = 0; i < array.size(); i++)
        {
          data_extract[i].push_back(array[i][user_id_iterator]);
        }
      }
      user_id_iterator++;
    }

    event_iterator++;
  }

  return data_extract;
}

给定的向量包含可变数量的字符串向量(至少2个)。我的方法应在

中搜索某些UserID。
check_id(user_ids, array[0][user_id_iterator])

然后将所有1D向量的相关事件(user_id_iterator)推送到新的2D向量中

vector[i:in][user_id_iterator]

进入新启动的向量

std::vector<std::vector<std::string>> data_extract;

通过for循环。

 for (size_t i = 0; i < array.size(); i++)
    {
      data_extract[i].push_back(array[i][user_id_iterator]);
    }

这一切都按预期进行,直到将[user_id_iterator]行中的vector [i:in]的元素推入空向量中为止。

我是否必须初始化2D Vector data_extract中的所有1D矢量?填充向量的空向量的正确语法是什么? 我收到异常(分段错误),因为未正确初始化空向量。

2 个答案:

答案 0 :(得分:2)

您犯了一个简单的错误,很容易修复。

您的二维矢量

std::vector<std::vector<std::string>> data_extract;
定义后

为空。这意味着,它不包含任何元素。甚至不是索引为[0][0][0]的元素。因此,您遇到了段错误,因为您正在访问元素[i],该元素不存在。

因此,是的,正如您所假设的,您必须初始化向量。有几种可能性。您可以使用here中所述的std::vector构造函数来设置初始大小。 3)或4)

例如:

std::vector<std::vector<std::string>> data_extract(array.size());

哪个可能是最合适的解决方案。

您也可以在定义后resize将向量

data_extract.resize(array.size());

但这是不需要的另一行代码,因为您可以在构造函数中进行操作。如果知道第二维的大小,当然也可以初始化向量的两个维。

std::vector<std::vector<std::string>> data_extract(array.size(),std::vector<std::string>(array[0].size(),""));

顺便说一句。您的外部while循环是禁止操作的。

while (event_iterator <= nr_of_events)

“ event_iterator”在循环正文中无处使用,并且内部while循环永远不会运行。这是因为,在外循环的第二轮中,“ user_id_iterator”已经比“ array [0] .size()”更小,并且内循环将永远不会运行。

其余的逻辑也很难理解。我不确定,为什么总是引用“ array [0]”。

答案 1 :(得分:1)

由于实现功能的方法过于复杂,因此很难找到细分错误。有一些简单的重构措施,可以减少此处产生的噪声:

调用字符串向量 array 的向量确实很烦人。而是尝试对其重命名和别名(不完全了解您的上下文):

using TUserIdEvents = std::vector<std::vector<std::string>>;

TUserIdEvents extract_data_on_userid(const TUserIdEvents &eventsOfUserIds, std::vector<std::string> &user_ids, const int nr_of_events)
{
  TUserIdEvents data_extract;

您可以在单个for循环中完成所有操作,而不必在变量声明和迭代之外使用while循环:

// Loop which extracts the events based on user IDs  
for (int event_iterator = 0; event_iterator <= nr_of_events; ++event_iterator)

内部while可以替换为基于范围的for循环,因此您无需跟踪另一个int-iterator:

// Loop which finds specified user id in an event
for (const auto& userIdsOfEvent : eventsOfUserIds[0])
{
    if (check_id(user_ids, userIdsOfEvent))
    {
       for (size_t i = 0; i < eventsOfUserIds.size(); i++)
       {
          data_extract[i].push_back(userIdsOfEvent);
       }
    }
}

这给我们带来了您的实际问题:

data_extract[i].push_back(array[i][user_id_iterator]);

您正在使用迭代器data_extract访问i,但是data_extract尚未在D1级别上初始化。为此,您可以按以下方式构造它:

TUserIdEvents data_extract(eventsOfUserIds.size());

这将在data_extract中创建子向量的数量,等于作为参数传递的子向量的数量。