C++: How to make break/continue in nested loops - c++

How to beautifully implement the following code?
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int k = 0; k < l; k++) {
if (condition1) {
// continue at for k ...
}
if (condition2) {
// continue at for j ...
}
if (condition3) {
// continue at for i ...
}
}
}
}
Usually I'll go with three boolean flag, and after each iteration will check it whether I should break/continue. Is there better way to do that? I was taught never to use goto/labels but looks like it might be useful here?

Related

How can I circle back to the a starting point using a for loop?

I have a std::vector<std::unique_ptr<object>> myObjects_ptrs. I need to, starting in one of my objects, circle back again to where I started.
I am doing this as follows:
while(true)
{
for(int i = 0; i < myObjects_ptrs.size(); ++i)
{
myObjects_ptr[i]->doSomething();
//and here I need to circle back
for(int j = i + 1; j < myObjects_ptr.size(); ++j)
{
//do some things with each other object
}
for(int j = 0; j < i; ++j)
{
//do the same things with the rest of the objects
}
}
}
Is this the standard way of doing that? My problem is that once I detect something, then I dont need to keep going around. For example if I find something during the first loop then there is no need to go through the second loop. I con solve this by adding an extra if before the second loop; but is there a better way?
You could use a modulus, i.e. the two inner loops would become:
int numObjects = myObjects_ptr.size();
for (int j = i + 1; j < numObjects + i + 1; ++j)
{
// Get object
auto& obj = myObjects_ptr[j % numObjects];
}
You could replace the two inner loops with something like this:
for(int j = i + 1;; j++)
{
j %= myObjects_ptr.size();
if (j == i)
{
break;
}
// Do stuff
}

C++ vector is declared 1D but accessed in a 2D way

I found some C++ code on the internet and I had a problem trying to understand it. So I have an array of Strings called vetor with 105 positions. After the declaration there's an if statement that tries to access the array like a matrix. How is that possible?
string vetor[105];
for(int k = 0; k < n; ++k) {
bool ok = true;
for(int i = 0, i < (int((text).size()))-(int((vetor[k]).size()))+1; ++i) {
ok = true;
for(int j = 0, j < (int((vetor[k]).size())); ++j) {
if(text[i+j] != vetor[k][j]) {
ok = false;
break;
}
}
if(ok) {
res.push_back(ii(i, i-1+(int((vetor[k]).size()))));
}
}
}

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;
}
}
}
}

Get rid of goto statement from embedded C/C++ logic

I want to get rid of this goto statement. Can any one tell me the logic for the same. The code below is not the exact code that I want to modify, but it will support my question. Please don't ask the significance of the code when commenting on this post as it is just an example.
int result[i][j];
for (int i = 0; i<100; i++)
{
for (j = 0; j<100; j++)
{
result[i][j] = j++;
if (j == 80)
goto break1;
}
}
break1:
…;
Put those loops in a function, give it a proper name and return; when it is done. If it is complicated enough to need two loops, it deserves a name.
A finished flag is so hard to read that you should put that construct in its own function anyway, making it obsolete.
Exceptions are only for errors you cannot handle locally. Use them to notify higher level functions that something you cannot fix went wrong, not if something that was supposed to happen happened.
I would see three possible solutions.
Put the code into a function and leave that function with return
Use a "finished" flag like already demonstrated well in the answers by Michel Keijzers, Bas in het Feld and EvilTeach.
(C++ only) surround the code-section with a try-catch-block and throw and exception when you want to leave the code. But keep in mind that exceptions are usually supposed to be used for error-handling. So you should only use this pattern when terminating the loops is the result of an error conditions.
Since you want to break two loops, you have to notify the outer loop. You can do this by having a boolean that checks for that:
bool break_loop = false;
for (int i = 0; i < 100; ++i) {
for (int j = 0; j < 100; ++j) {
if (j == 80) {
break_loop = true;
break;
}
}
if (break_loop) break;
}
Use a boolean to break from the for loop(s).
int result[i][j];
bool cont = 1;
for (int i =0;i<100;i++)
{
for(j = 0;j<100;j++)
{
result[i][j] = j++;
if(j == 80)
{
cont = 0;
break;
}
}
if (cont == 0)
break;
}
break1;
(note: not tested on real compiler).
int result[i][j];
for (int i = 0; i<100; i++)
{
for (j = 0; j<100; j++)
{
result[i][j] = j++;
if (j == 80)
{
i = 100;
break;
}
}
}
I sometimes like changing the control variable(s)
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
/* work */
if (j == 80) i = j = 100; // 100 makes both loops terminate
}
}
int result[i][j];
for (int i = 0; i<100; i++)
{
int j;
for (j = 0; j<100; j++)
{
result[i][j] = j++;
if (j == 80)break;
}
if(j == 80) break;
}
Know this is an old question but can be modified simply

Unique set of words from string C++

I am trying to write a function that inputs an array_string and finds unique words, then copies them over to unique_array. This is a bit over my head I feel like and need some advice on where to go from here..
void unique140(string str_array[], int array_size, string unique_array[], int&unique_size)
{
int i = 0;
int j = 0;
for(i = 0; i < array_size; i++)
{
for(j = 0; j < unique_size; j++)
if (str_array[i] != unique_array[j])
{unique_array[i];}
if(str_array[i] == unique_array[j]
break;
}
Try something like:
void unique140(string str_array[], int array_size,
string unique_array[], int&unique_size)
{
unordered_map<string,int> count;
for(int i=0; i<array_size; i++) {
count[str_array[i]]++;
}
unique_size = 0;
for(auto it=count.begin(); it!=count.end(); ++it) {
if(it->second==1) {
unique_array[unique_size++] = it->first;
}
}
}
use a std::map if you dont have a std::unordered_map.
You're not a million miles away, the loops look good. Now you have to use those loops to make a decision, is the word str_array[i] present in the unique_array or not? Now just a minutes thought will tell you that str_array[i] is present if any one of the equality tests str_array[i] == unique_array[j] is true. Here's how to code that
for(i = 0; i < array_size; i++)
{
bool in_unique_array = false;
for(j = 0; j < unique_size; j++)
if (str_array[i] == unique_array[j])
in_unique_array = true;
...
}
Next we have to add str_array[i] to unique_array if it's not already there. So that's
for(i = 0; i < array_size; i++)
{
bool in_unique_array = false;
for(j = 0; j < unique_size; j++)
if (str_array[i] == unique_array[j])
in_unique_array = true;
if (!in_unique_array)
{
...
}
}
Finally having decided to add the string to unique_array we have to do that
for(i = 0; i < array_size; i++)
{
bool in_unique_array = false;
for(j = 0; j < unique_size; j++)
if (str_array[i] == unique_array[j])
in_unique_array = true;
if (!in_unique_array)
{
unique_array[unique_size] = str_array[i];
unique_size++;
}
}