Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to shorten this while condition?

while (temp->left->oper == '+' || 
       temp->left->oper == '-' || 
       temp->left->oper == '*' || 
       temp->left->oper == '/' || 
       temp->right->oper == '+' || 
       temp->right->oper == '-' || 
       temp->right->oper == '*' || 
       temp->right->oper == '/')
{
    // do something
}

For clarity: temp is a pointer that points to following node structure:

struct node
{
    int num;
    char oper;
    node* left;
    node* right;
};
like image 406
Lukáš Pištěk Avatar asked Jul 23 '19 05:07

Lukáš Pištěk


People also ask

Why does my while loop not stop?

The issue with your while loop not closing is because you have an embedded for loop in your code. What happens, is your code will enter the while loop, because while(test) will result in true . Then, your code will enter the for loop. Inside of your for loop, you have the code looping from 1-10.

What is while loop in C?

The do/while loop is a variant of the while loop. This loop will execute the code block once, before checking if the condition is true, then it will repeat the loop as long as the condition is true.

Why for loop is better than while?

For loops (at least considering C99) are superior to while loops because they limit the scope of the incremented variable(s). Do while loops are useful when the condition is dependant on some inputs. They are the most seldom used of the three loop types.

What is the syntax of do while loop?

The syntax for a do while statement is: do loop_body_statement while (cond_exp); where: loop_body_statement is any valid C statement or block.


4 Answers

Sure, you could just use a string of valid operators and search it.

#include <cstring>

// : :

const char* ops = "+-*/";
while(strchr(ops, temp->left->oper) || strchr(ops, temp->right->oper))
{
     // do something
}

If you are concerned about performance, then maybe table lookups:

#include <climits>

// : :

// Start with a table initialized to all zeroes.
char is_op[1 << CHAR_BIT] = {0};

// Build the table any way you please.  This way using a string is handy.
const char* ops = "+-*/";
for (const char* op = ops; *op; op++) is_op[*op] = 1;

// Then tests require no searching
while(is_op[temp->left->oper] || is_op[temp->right->oper])
{
     // do something
}
like image 195
paddy Avatar answered Oct 19 '22 23:10

paddy


Yes, indeed you can!

Store the valid-characters to a std::array or even a plain array and apply the standard algorithm std::any_of to it for checking the condition.

#include <array>     // std::array
#include <algorithm> // std::any_of

static constexpr std::array<char, 4> options{ '+', '-', '*', '/' };
const auto tester = [temp](const char c) { return temp->left->oper == c || temp->right->oper == c; };
const bool isValid = std::any_of(options.cbegin(), options.cend(), tester);

while(isValid) // now the while-loop is simplified to
{
    // do something
}

This can be more cleaned by packing into a function, which accepts the node object to be checked.

#include <array>     // std::array
#include <algorithm> // std::any_of

bool isValid(const node *const temp) /* noexcept */
{
   static constexpr std::array<char, 4> options{ '+', '-', '*', '/' };
   const auto tester = [temp](const char c) { return temp->left->oper == c || temp->right->oper == c; };
   return std::any_of(options.cbegin(), options.cend(), tester);
}

which can be called in the while-loop

while (isValid(temp)) // pass the `node*` to be checked
{
    // do something
}
like image 38
JeJo Avatar answered Oct 19 '22 23:10

JeJo


Create a sub function,

bool is_arithmetic_char(char)
{
// Your implementation or one proposed in another answers.
}

and then:

while (is_arithmetic_char(temp->left->oper)
    || is_arithmetic_char(temp->right->oper))
{
    // do something
}
like image 45
Jarod42 Avatar answered Oct 19 '22 23:10

Jarod42


C-style:

int cont = 1;
while(cont)
    switch(temp->left->oper) {
    case '+':
    case '-':
    ...
    case '/':
        // Do something
        break;
    default:
        cont = 0;
    }

You might need to enclose // Do something with curly braces if you're going to declare variables.

like image 39
MCCCS Avatar answered Oct 20 '22 01:10

MCCCS