Iterate over vectors with n and n*n elements - c++

I have this Google test assertions
ASSERT_FLOAT_EQ(longerVector[0], shorterVector[0]);
ASSERT_FLOAT_EQ(longerVector[1], shorterVector[1]);
ASSERT_FLOAT_EQ(longerVector[2], shorterVector[2]);
ASSERT_FLOAT_EQ(longerVector[3], shorterVector[0]);
ASSERT_FLOAT_EQ(longerVector[4], shorterVector[1]);
ASSERT_FLOAT_EQ(longerVector[5], shorterVector[2]);
ASSERT_FLOAT_EQ(longerVector[6], shorterVector[0]);
ASSERT_FLOAT_EQ(longerVector[7], shorterVector[1]);
ASSERT_FLOAT_EQ(longerVector[8], shorterVector[2]);
as you can see, there are two vectors, shorter with n elements and longer with n*n elements (in this case 3 and 9 respectively).
How could I create two nested for loops, which would make my code shorter and simpler?
I tried for example this but it failed. I understand why but I was not able to come up with anything better.
for(size_t i = 0; i < shorterVector.size(); i++)
{
for(size_t j = 0; j < shorterVector.size(); j++)
{
ASSERT_FLOAT_EQ(longerVector(i*j), shorterVector(j);
}
}
Thank you very much for any help and I apologize for maybe a dumb question.

Use this instead
for(size_t i = 0; i < longerVector.size(); i++)
{
ASSERT_FLOAT_EQ(longerVector[i], shorterVector[i%3]);
}

for(size_t i = 0; i < shorterVector.size(); i++)
{
for(size_t j = 0; j < shorterVector.size(); j++)
{
ASSERT_FLOAT_EQ(longerVector[i*shorterVector.size() + j], shorterVector[j]);
}
}
You should assert before that shorterVector.size() * shorterVector.size() == longerVector.size().
If you do not want to have the multiplication in the inner loop body you can do:
for(size_t i = 0, k = 0; i < shorterVector.size(); i++)
{
for(size_t j = 0; j < shorterVector.size(); j++)
{
ASSERT_FLOAT_EQ(longerVector[k++], shorterVector[j]);
}
}

Related

Which is better, a single for loop or double for loop to iterate through 2-D array? C++

Let's say that I have a 9-by-9 2-D array. Is there a difference between looping through with a single loop or multiple loops?
for (int i = 0; i < 81; i++)
currentEdit[i / 9][i % 9] = 0;
VS.
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
currentEdit[i][j] = 0;
The right choice is multiple loops. Keep in mind that it will perform much less operations since it does not have to divide or calculate the module to access the array position.
This is the right choice:
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
currentEdit[i][j] = 0;

Copying values of 2D array into another

I have a 2D array that I want to assign the values of another array. I'm making a game of life simulator and have everything else working but this. My code is this:
for(int i = 0; i < ROWS; i++) {
for (int j = 0; i < COLS; j++) {
current[i][j] = next[i][j];
}
}
current and next are both bool's. I keep getting the error code EXC_BAD_ACCESS in X-Code. I'm unsure what I'm doing wrong
To re-iterate my comment, the innerloop compares i with COL rather than j. So
for(int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
current[i][j] = next[i][j];
}
}
should solve the issue

How can I not allow an element in an array to not increment if it was already incremented on that run in the loop?

I am trying to get the summary of CFG with given input. I have to list the terminals with the count of how many times it appears in the rule. However, I'm having trouble with it counting multiple terminals on the same rule.
for (int i = 0; i < cfg.size(); i++)
{
for (int j = 0; j < cfg[i].size(); j++)
{
for (int k = 0; k < terminal.size(); k++)
{
if (strcmp(cfg[i][j].c_str(), terminal[k].c_str()) == 0)
{
//TO-DO if counter[k] already incremented do not increment counter[k] again
counter[k]++;
break;
}
}
}
}
For example if the rule is
Z -> a b b b
It will return 3 for b when the correct answer would be 1.
Any help on how I can how I can leave that rule after it has already been counted would be great. Thank you
I'm not sure if I understand what you mean, but maybe changing the loops order would help?
for (int i = 0; i < cfg.size(); ++i)
{
for (int k = 0; k < terminal.size(); ++k)
{
for (int j = 0; j < cfg[i].size(); ++j)
{
if (strcmp(cfg[i][j].c_str(), terminal[k].c_str()) == 0)
{
++counter[k];
break;
}
}
}
}

C++ create array with dynamic size

How can I create a array with dinamic size like this:
int sentLen = sentences.size();
double a[sentLen][sentLen];
for (int i = 0; i < sentLen; i++)
{
for (int j = 0; j < sentLen; j++)
{
a[i][j] = somefunction(i, j);
}
}
My research led me to malloc which isn't recommended or other too complicated methods. After I realised that size must be constant, I tried using unordered_map, and I have tried the following:
std::unordered_map <int, int, double> a;
for (int i = 0; i < sentLen; i++)
{
for (int j = 0; j < sentLen; j++)
{
a.insert({ i, j, somefunc(i, j) });
}
}
but still unsuccessful.
You don't really want to use arrays.
std::vector<std::vector<double>> a{
sentLen, std::vector<double>{ sentLen, 0.0 } };
for (int i = 0; i < sentLen; ++i)
{
for (int j = 0; j < sentLen; ++j)
{
a[i][j] = somefunc(i, j);
}
}
You're getting an error because you can't use variables as static array sizes. They must be known at compile time. You have to allocate dynamically or use a vector instead.

How to put NULL in all cells of a matrix vector?

i'm trying to initialize all cells of a matrix with NULL values, but something is wrong here.
the code :
vector<vector<Distance*> > distanceMatrix;
for (int i = 0; i < 7 ; i++)
for (int j = 0; j < 7 ; j++)
distanceMatrix[i][j].push_back(NULL);
i bet it's something stupid, thanks for the help.
From the std::vector reference page:
Vectors can be constructed with some values in them.
You may try:
vector<vector<Distance*> > distanceMatrix(7, vector<Distance*>(7, NULL));
Also, regarding your problem:
vector<vector<Distance*> > distanceMatrix;
for (int i = 0; i < 7 ; i++)
for (int j = 0; j < 7 ; j++)
distanceMatrix[i][j].push_back(NULL); //1
When you code first reach //1, distanceMatrix[i] resolves to distanceMatrix[0] but you did not call distanceMatrix.push_back(vector<Distance*>()) so you are referring to a non initialized cell.
To correct code would have been:
vector<Distance*> vec;
for (int j = 0; j < 7 ; j++)
vec.push_back(NULL);
vector<vector<Distance*> > distanceMatrix;
for (int i = 0; i < 7 ; i++)
{
distanceMatrix.push_back(vec);
}
Which is still far worse than my first suggestion.
Since the matrix is empty to begin with, you need to push_back every value and every row, not depending on its position in the matrix:
vector<Distance*> row;
for(int j=0; j < 7; j++)
row.push_back(NULL);
vector<vector<Distance*> > distanceMatrix;
for(int i=0; i < 7; i++)
distanceMatrix.push_back(row);