Pushing back a vector of strings into a 2D vector - c++

I am currently working in C++, dealing with string vectors.
Let's say I have a 1D string vector called 'temp.' At each index of 'temp', there is a string containing three words/chars. Let's say that temp[0] = "Hello hi 3"
I have defined a function called 'splits' which takes in some string, and removes the whitespaces, and places the result in a string vector called 'res'. So, using the 'splits' function on temp[0] results in:
res[0] = hello
res[1] = hi
res[2] = 3
I would like to use the "splits" function on each string held in 'links,' and pass it into a 2d vector of strings called 'totalResults.' As I do not know the size of 'links' I know that I will need to dynamically allocate this 2D vector of strings.
So far I have:
vector<vector<string>> totalResults //dynamically allocated 2d vector of strings
vector<string> temp;
for (int i = 0; i<rows; i++)
{
for (int j = 0; j<cols; j++)
{
temp=splits(links[j])
totalResults[i][j].push_back(temp[0][j]));
//using splitting function on links[i], and pushing it into the 2d vector
}
}
In this example, I would like "hello" to go into totalResults[0][0], "hi" to go into totalResults[0][1], and "3" to go into totalResults[0][2].
In the second row of totalResults, I would like the same assignment to occur, but when 'splits' is used on 'links[1]'.
I have testing the 'splits' function in isolation, and it works as I expect it to, so I am assuming the error may be in how I am pushing back values into this 2d vector. I am testing the resulting 2D matrix, but nothing is printing... Are the values not actually being pushed in?
I appreciate any help/ideas!
Thank you! :)

Based on your description, links has cols elements, and you want to split each links[j] and add it to totalResults:
vector<vector<string>> totalResults(cols);
for (int j = 0; j < cols; j++)
{
totalResults[j] = splits(links[j]);
}

Related

Segmentation Fault in C++ while using string vectors

My code is for an online coding practice site, I have been doing many of the challenges but I cannot seem to get around the segmentation fault error on this one.
The aim of the code is to find the longest length strings in a string vector (up to 10 strings long) and then to return a string vector containing just those longest strings in order.
I believe logically my code works, but I can't test it. I am still new to vectors so can't seem to properly understand other answers on here in relation to my issue.
vector<string> allLongestStrings(vector<string> inputArray) {
vector<string> longestStrings; // vector
int longest_size = longestStrings.size(); // int
int longestArrayCounter = 0; // int. For filling longestStrings whenever
// there is a long string
int longest_string = 0; // int. For recording the size of the longest string
for (int i = 0; i < inputArray.size(); i++) {
// Loop will:
//1. Measure size of string in input array
//2. if longest will change value of longest_string and clear longestStrings
//3. If the same length as longest_string will add it to longestStrings vector
//4. if it is shorter it will be ignored
if (inputArray[i].size() > longest_string) { // input vector
longest_string = inputArray[i].size(); // vector
longestStrings.clear(); //clearing the vector to only store longest string values
longestArrayCounter = 0; //reset counter for longestStrings
longestStrings[longestArrayCounter++] = inputArray[i];//puts new longest string from input into my vector
}
if (inputArray[i].size() == longest_string) {
longestStrings[longestArrayCounter++] =inputArray[i];// my vector and input vector
}
}
return longestStrings;
}
longestStrings.clear();
longestArrayCounter = 0;
longestStrings[longestArrayCounter++] = inputArray[i];
is bad because you are doing assignment to non-existent element.
Instead of the two
longestStrings[longestArrayCounter++] = inputArray[i];
you should do
longestStrings.push_back(inputArray[i]);
Then, std::vector will manage the size for you, so you don't have to manage longestArrayCounter by yourself. Use longestStrings.size() to obtain the size.

Dynamic 2D array of strings where the second dimension can change

So I have to make a 2-d array of strings named history[][], where history[i] stores all of the subjects currently involved in experiment i, and history[i][j] contains a string listing all of the experiments that this particular subject has been a part of. The thing is, I have to use int* numsubjects, an array of integers that tells me how many subjects are in experiment i. However, the contents of numsubjects should be able to move around as subjects can be moved into other experiments. I have no idea how to go about doing this. I cannot use vector, dequeue, or list.
experiments = 0;
numsubjects = new int[experiments+1];
numsubjects[experiments] = n;
history = new string*[0];
for(int j = 0; j < n; j++) {
history[0] = new string[j];
history[0][j] = "0";
}
The above code initializes everything when there is only one experiment, experiment 0. I need a way to make history somehow with numsubjects in it.
If you must use C-style arrays, then realloc() will allow you to resize your array.
However, since this is C++, I strongly encourage you to use std::vector or std::map.

trying to load info from a vector containing classes into a two dimensional string vector

I use an input function I made to take info from a text file and input it into the private fields of a class let's call it student, each time a record is filled with the first row from the text input file I push_back the filled class in the vector students to end up with a vector containing classes which contain the data from the input file.
So now in order to be able to perform manipulations on this data I want to load it into a two dimensional string vector but I'm having a hard time implementing this. Below is how far I have gotten, I feel like at this point I'm running in a circle. Any help is appreciated.
The parameter passed (size) is how many rows there are in the text file which is checked prior to this function running.
void student::loadData(int size)
{
vector <vector<string> > tempVec(size);
string first, middle, last, addressNum, addressStreet,
phone, gender, email, emContactFirst, emContactLast,
ph, emPhone, ID, age;
//FIXME//
for (vector<student>::iterator it = students.begin(); it != students.end(); it++){
for (int i = 0; i < size; size++)
{
tempVec[size].push_back(it->getName());
tempVec[size].push_back(it->getId());
tempVec[size].push_back(it->getAge());
tempVec[size].push_back(it->getPhone());
tempVec[size].push_back(it->getAddress());
tempVec[size].push_back(it->getEmail());
tempVec[size].push_back(it->getEmPhone());
tempVec[size].push_back(it->getEmContact());
tempVec[size].push_back(it->gpa);
tempVec[size].push_back(it->honors);
tempVec[size].push_back(it->major);
it++;
}
}
//trying to output 2-dimensional array for debugging purpouses
//(trying to mimic what the output file would look like)
for (int i = 0; i < size; size++)
{
for (vector<string>::iterator z = tempVec[size].begin(); z != tempVec[size].end(); z++){
//**FIX ME**//;
}
}
}
There are several problems here. Don't increment size in the for loops, you want to increment i.
tempVec[size] is outside the bounds of the vector. You want tempVec[i] instead.
Don't increment it inside the inner for loop.

how to add element into the nested vector

Hello sorry for the stupid question but I am very beginner in c++. I cannot describe the problem well because of my bad English. I'll add my code here that i have tried so far.
vector< vector<string> >allData;
int main(){
vector<string>test;
for(int i = 0; i<allData.size(); i++){
test = allData[i];
}
int id;
cout<<"enter Id"<<endl;
cin>>id;
if (id == test[2]){
string desc;
cout<<"enter ur description"<<endl;
cin>>description;
allData.push_back(description);
} else {
cout<<"there is no data with the id u have entered"<<endl;
}
}
Above code is just an example code. Lets say that there are 2 vectors inside the vector named allData, so when i enter the ID of a first vector i can add description into the vector which i have chosen by choosing it by its Id. Somehow i cannot do that thing like choosing the first or second vector by inputing their ids then add more datas into chosen 1. So please someone tell me what should i do. I know that above code is incomplete and awful but as i said before i am very beginner in c++
You can add values into nested vector just like a normal vector. So you could do allData[i].push_back(description) or even allData[i][j] = description to overwrite an existing value. However you are trying to push a string into allData which does not contain strings but rather Vectors of strings.
Additionally your first for loop runs through allData and saves each to test, overwriting test each time. When the loop is done test will simply contain the last element of allData. Thus your for loop is the equivalent of doing test = allData.back()
Well, if you need to access your child vectors directly, you need to declare your vector saying how many child vectors it has (without this, you have segmentation fault when trying to access it ie. allData[0] will be unitialised).
Let's say you have 2, so they will be allData[0] and allData[1], just like a normal array.
std::vector<std::vector<std::string>> allData (2);
allData[0].push_back("string0a");
allData[0].push_back("string0b");
allData[1].push_back("string1");
for(auto & a : allData[0])
std::cout << a << "\n";
Of course, you can add vectors dinamically too.
std::vector<std::vector<std::string>> allData;
std::vector<std::string> child0;
child0.push_back("string0");
allData.push_back(child0);
And to check if the id the user input is valid, you can do
if(id >= 0 && id < allData.size()) {
....
Your variable all_data is a vector of vectors representing rows and columns. You can create a scratch vector for a row, push_back() data on that scratch vector, then push_back() that scratch vector onto all_data like so:
#include <vector>
int main() {
std::vector<std::vector<int>> all_data;
for (int ii = 0; ii < 10; ii++) {
std::vector<int> row_data;
for (int jj = 0; jj < 10; jj++) {
row_data.push_back(ii * jj);
}
all_data.push_back(row_data);
}
return (0);
}

How to split vector into subsets?

I'm trying to split the vector into subsets based of the number of process I use in my application. I created the pseudo code but I really don't have any clue how can I output the subsets.
The problem:
Read a subset of the address records from residences.dat using
striping. For n processes, each process evaluates a unique subset of
records based on every nth record. The number of records in this
subset should be approximately #-of-residence-records /#-of-processes. Across all the parallel processes used no address should be omitted and none should be processed more than once. Also
note that only ONE record at a time should be stored in memory by any
process
My code:
std::vector<Residence> spliteResidenceDaata(vector<Residence> rs,int numProces = 0);
function body
std::vector<Residence> spliteResidenceDaata(vector<Residence> rs,int numProces)
{
std::vector<Residence> residenceSet;
//get the size of vector
int res_set_size = rs.size();
int sizrOfSubSet =res_set_size/numProces;
//output the arry subsite some "help here"
return residenceSet;
}
update
I came up with this pseudo code
1-take the number of line in .dat file rData
2- get the number of data you want to read for each process sizeofLine (rData.size()/numProc)
3- read the .dat file from line 0 to sizeofLine
4-output array
i haven't tested this code, but something along the lines of this should work - instead of having your function return one vector, have it return a vector of vectors, like this:
std::vector<std::vector<Residence>> split(std::vector<Residence rs, int num_procs)
this will allow you to split your original vector into num_procs number of vectors, and then push_back() each of those onto your return vector of vectors (kind of like a matrix).
std::vector<std::vector<Residence>> split(const std::vector<Residence> rs, const unsigned num_procs) {
unsigned j = 0; //position counter
std::vector<std::vector<Residence>> result; //resulting vector of vectors
for(unsigned i = 0; i < num_procs; ++i) { //for each process
std::vector<Residence> temp; //create a vector
for(; j < ((i + 1) * rs.size() / num_procs; ++j) //iterate
temp.push_back(rs[j]); //and populate temporary vector with a 1/num_procs section of original vector
result.push_back(temp); //and push that temporary vector into your result vector of vectors
}
for(; j < rs.size(); ++j) //finally, if the original vector is not divisible by num_procs
result[num_procs].push_back(rs[j]); //push the remainder of elements into the last vector
}
when you call the function, it will look something like this:
std::vector<std::vector<Residence>> vectors = split(original_vector, 4);
which will allow you to get subvectors like this:
vectors[0]; //first quarter
vectors[1]; //second
vectors[2]; //third
vectors[3]; //fourth + remainder
you need to read one record at time not pass the all subset as vector think you need this
while(!residenceFile.eof())
{
residenceFile >> res.x >>res.y;
if ( numLines % numProcs == rank)
{
//call the process
//populate_distancesVector(res,foodbankData);
analysis_range(populate_distancesVector(res,foodbankData),count);
}
++numLines;
}