Push_back на 2D вектор через цикл

Я пытаюсь выучить C ++ и наткнулся на эту постановку задачи

ОПИСАНИЕ ВЫЗОВА:

Наш отдел маркетинга только что заключил сделку с несколькими местными торговцами, которая позволит нам предлагать эксклюзивные скидки на различные продукты нашим лучшим клиентам каждый день. Суть в том, что мы можем предложить каждый продукт только одному клиенту, и мы можем предложить только один продукт каждому клиенту.

Каждый день мы будем получать список продуктов, которые имеют право на эти специальные скидки. Затем мы должны решить, какие продукты предложить нашим клиентам. К счастью, наша команда высококвалифицированных статистиков разработала удивительную математическую модель для определения вероятности того, что данный клиент купит предложенный продукт, путем расчета того, что мы называем «оценкой пригодности» (SS). Совершенно секретный алгоритм для расчета SS между клиентом и продуктом:

1. Если количество букв в названии продукта является четным, то SS — это число гласных (a, e, i, o, u, y) в имени клиента, умноженное на 1,5.
2. Если количество букв в названии продукта нечетно, то SS — это число согласных в имени клиента.
3. Если количество букв в названии продукта совпадает с какими-либо общими факторами (кроме 1) с количеством букв в имени клиента, то SS умножается на 1,5.

Ваша задача — внедрить программу, которая назначает каждому покупателю продукт, который будет предлагаться таким образом, чтобы максимизировать суммарный общий SS по всем выбранным предложениям. Обратите внимание, что может быть разное количество продуктов и клиентов. Вы можете включать код из внешних библиотек, если вы цитируете источник.

ОБРАЗЕЦ ВВОДА:

Ваша программа должна принять в качестве единственного аргумента путь к файлу. Каждая строка в этом файле представляет собой один контрольный пример. Каждый тестовый набор будет представлять собой набор имен клиентов, разделенных запятыми, за которыми следует точка с запятой, а затем набор имен продуктов, разделенных запятыми. Предположим, что входной файл в кодировке ASCII. Например (ПРИМЕЧАНИЕ. В приведенном ниже примере есть 3 контрольных примера):

Джек Абрахам, Джон Эванс, Тед Дзюба, iPad 2 — 4 шт., Девушки-скауты, Тонкие мяты, Арбалет Nerf

Джеффри Лебовски, Вальтер Собчак, Теодор Дональд Керабатсос, Питер Гиббонс, Майкл Болтон, Самир Нагиенанажар; & Половина, мяч для боулинга Colt M1911A1, 16 фунтов, красный степлер Swingline, бумага для принтера, подписка на журнал Vibe — 40 шт.

Jareau Wade, Rob Eroh, Mahmoud Abdelkader, Wenyi Cai, Джастин Ван Винкль, Gabriel Sinkin, Aaron Adelson, Batman № 1, футбол — официальный размер, наушники с усилением басов, еда для слонов — 1024 фунта, футболка Three Wolf One Moon, Дом Периньон 2000 Винтаж

ВЫБОР ОБРАЗЦА:

Для каждой строки ввода выведите максимальный общий счет с точностью до двух десятичных знаков. Для приведенного выше примера ввода вывод должен выглядеть следующим образом:

21,00
83,50
71,25

В моей программе я создал 2D вектор строк

`std::vector<std::vector<std::string>`

Я хочу сохранить имена в каждой строке входного файла в виде строк второго измерения

скажем, имя 2D-вектора и у меня есть строка «Дексобокс Валектра»
который должен быть помещен на место а [0] [0] если векторы можно рассматривать как массив.

То, что я пытался использовать для push_back: а [я] .push_back (маркер) который компилируется, но приводит к ошибка сегментации во время выполнения.

Как это исправить? Есть ли другой способ подтолкнуть во 2-м измерении вектора?

Я использую процедуру для разделения имен с разделителями-запятыми и push_back в вектор

вот фрагмент кода:

void comma_seprate(std::string s, std::vector < std::vector<std::string> >& a , int i)
{
std::istringstream ss(s);
std::string token;
int j = 0;
while(std::getline(ss, token, ','))
{
a[i].push_back(token); //this is  the line causing segmentation fault at runtime
std::cout << token << std::endl;
j++;
}
}

Вот полный код:

#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
#include <vector>
#include <sstream>

#define DEBUG

void comma_seprate(std::string s, std::vector < std::vector<std::string> >& a , int i)
{
std::istringstream ss(s);
std::string token;
int j = 0;
while(std::getline(ss, token, ','))
{
a[i].push_back(token);
std::cout << token << std::endl;
j++;
}
}

void split_string( std::string s, std::vector<std::string>& v, std::vector<std::string>& u )
{
std::string delimiter = ";";
v.push_back (s.substr(0, s.find(delimiter)));
u.push_back (s.substr(s.find(delimiter)+1,s.size()));
}

int main ( int argc, char** argv )
{
//variable for file name
std::string filename;
//error handling for invalid argument size
if ( argc > 2 || argc < 2 )
{
std::cerr <<"filename missing! Usage: " << argv[0] << " <input_filename>"<< std::endl;
return EXIT_FAILURE;
}
//=========================================================================
//Using C style debugging : Any other way to do this in c++?
#ifdef DEBUG
std::cout << "filename :"<<filename << "\t  num_arguments: " << argc << std::endl;
#endif
//=========================================================================
//opening the file for reading
std::ifstream in(argv[1]);
std::vector<std::string> line_vec;
std::string temp_line;
int line_count = 0;
while(std::getline(in,temp_line))
{
line_count++;
//Ignores any empty lines in the input file
if(temp_line.empty())
continue;
line_vec.push_back(temp_line);
}

//=========================================================================
#ifdef DEBUG
std::cout <<"\nPrinting out contents of the line_vec" <<std::endl;
for (int i=0; i<line_vec.size();i++){
std::cout << line_vec[i] << std::endl;
}
std::cout << "The size of the line_vector is : " << line_vec.size() << std::endl;
#endif
//=========================================================================

//Now splitting line by semicolon for customer names and product name seperation
std::vector<std::string> customer_list;
std::vector<std::string> product_list;
for (int i=0; i<line_vec.size();i++)
{
split_string(line_vec[i], customer_list, product_list);
}

#ifdef DEBUG
std::cout <<"=======================================================================" <<std::endl;
std::cout <<"\nPrinting out contents of the customer_list " <<std::endl;
std::cout <<"=======================================================================" <<std::endl;
for (int i=0; i<customer_list.size();i++){
std::cout << customer_list[i] << "\n\n" << std::endl;
}
std::cout << "The size of the customer_list vector is : " << customer_list.size() << std::endl;
std::cout <<"=======================================================================" <<std::endl;
std::cout <<"\nPrinting out contents of the product_list " <<std::endl;
std::cout <<"=======================================================================" <<std::endl;
for (int i=0; i<product_list.size();i++){
std::cout << product_list[i] << "\n\n" << std::endl;
}
std::cout << "The size of the line_vector vector is : " << product_list.size() << std::endl;
#endif

//comma seprating the sting to get a list of customer names and product names
std::vector < std::vector < std::string > > customer_name;
std::vector < std::vector < std::string > > product_name;

for(int i =0; i< customer_list.size(); i++)
{
comma_seprate(customer_list[i],customer_name,i);
//comma_seprate(product_list[i],product_name,i);
}
}

1

Решение

Это означает, что a[i] не имеет ничего в этом, и это выходит за рамки.

У вас есть вектор векторов

std::vector < std::vector<std::string> >& a

так что вы отталкиваете элементы внутри второго вектора

std::vector < std::vector<std::string> >& a
// ^^^^^^^^^^^^^^^^^^^^^^^^ Inside this one here

но другой вектор все еще пустой

 std::vector < std::vector<std::string> >& a
//^^^^^^^^^^^  that one is empty

так что это нормально, если вы делаете a[i] падает … потому что его пусто.

Что вы могли бы сделать, это сначала создать внутренний вектор.

while(std::getline(ss, token, ','))
{
std::vector<std::string> inner_vector;
inner_vector.push_back(token);
a.push_back(inner_vector); //this is  the line causing segmentation fault at runtime
std::cout << token << std::endl;
j++;
}
0

Другие решения

Других решений пока нет …