If statement for multiple values of same variable - c++

I want to apply if statement to check a condition with multiple values, which I know should be something like this:
if (value == 1 || value == 2 || value == 3 || value == 4)
//Do something;
But this does not look good, isn't there any way to check like:
if(value == 1 || 2 || 3 || 4)
Note: I am not trying something in range like:
if (1 <= value && value <= 4)

No you can not write it as :
if(value==1 || 2 || 3 || 4)
You can use conditional statement for different conditions.

A possible simple alternative would be:
switch (value) { case 1: case 2: case 3: case 4: std::cout << "true"; }
Live sample
Wether it looks better or not is a matter of taste.
Another alternative would be:
switch (value) { case 1 ... 4: std::cout << "true"; }
Live sample
But this is not standard C++, I believe it's a GNU extension.

In case the range of possible values is smaller than the number of bits you can do something like this:
int value = 2;
auto values = {1,2,3,4};
int test = 0;
for(auto i : values)
test |= (1 << i);
if((1 << value) & test)
std::cout << "true" << std::endl;
If you have direct control over the possible values you can also directly set them as bitflags and skip the bitshift part.
Otherwise there is also the option of inverting the condition in case there are fewer possible values that should evaluate to false.
Also you could just loop over an array of valid values and see if any of them matches.

No you cannot write the way you have described. You still have option of switch case and ternary operators.
If you want to make it fancy you still have option like
vector<int> v = {1,2,3,4,5}; // desirable values
auto it = find(v.begin(), v.end(), value);
if(it != v.end()){
cout<<"value is equal to something!\n";
// if you want to check which value does it match to
cout<<"Matching value is at index "<<it-v.begin()<<"\n";
}else {
cout<<"Value is not equal to any number!\n";
}
For this you will need to include vector library by using #include <vector>

Well, I had the same issue and this is the solution I came up.
I created an array, with the values I want to check, and then I use the native array includes() method to check if the variable value exists on the array. Like this:
[1, 2, 3, 4].includes(value);
If the variable value exists on the array the includes() method will return a boolean with the value true. Otherwise it will return a boolean with the value false.

Related

what does if(!(x%3)) mean?

I am attempting to solve a hw problem in which I need to write down what the program will output. I am stuck however, on the syntax "if ( !(i%3)). What does that really mean? Does it mean that the program is checking for any i that is divisible by three? aka, is the if statement only runs if i is divisible by three?
int main () {
for (int i=0; i<10; (i<3?i++;i+=2)) {
if (!(i%3)) {
continue;
}
else if (i%7 ==0) {
break;
}
cout << i<< endl;
}
Does it mean that the program is checking for any i that is divisible by three? aka, is the if statement only runs if i is divisible by three?
Correct. The longer version of that check would be
if (i % 3 == 0)
continue;
The most common use case for such branching is probably FizzBuzz.
İt means if i is not(!) divisible by 3 continue.
For example if i is 3,6,9 it won't continue otherwise it will continue.
if (x) where x is int implicitly compared with zero. I.e. if (x) equals to if (x != 0). ! is negation. So if (!x) equals to if (x == 0). And the last step is if (!(i%3)) equals to if ((i%3) == 0) what is the same with check, that i deivisible by 3
The if() statement is false only if the result inside the parentheses is 0 (false). Take a look at your program:
i%3 may return 0 (false), 1 (true), or 2 (true)
The negation operator ! changes the result of the operation (i%3). So, if the i is divisible with 3 the statement will return 0 (false). Being negate, ! it will result in True. Otherwise the result of (i%3) will be true and with the operator ! the result of the hole statement will be false. Basically this code is checking if the value of i is divisible with 3.
Other options will be:
if (0==i%3)
{
/*code*/
}
Your code can be simplified as below
int main() {
for (int i=0; i<10;)
{
if (i % 3 == 0) {
continue;
}
else if (i % 7 == 0) {
break;
}
cout << i << endl;
i = i<3 ? i+1 : i+2;
}
}
When you write a integer variable like i as a condition, what happens is that if i==0 then the result of the condition is false, otherwise it would be true.
Let's check it out in your program, if(!(x%3)), let's name condition= !(x%3), when this condition is true? when x%3 == 0, note that the negation operator ! is behind x%3, so in this case the condition would be equal to true, more formally the condition is equal to :
if(x%3==0)
these kinds of conditions are common, check this example out :
int t = 10;
while(t--){
cout<<t<<endl;
}
The above condition i.e if(!(i%3)) will true when " i is not disvisable by 3"
Hope this helps.
In java and other languages there is a special type to represent booleans and evaluate expressions; in c and its variants there is no such thing, instead an expression is considered "true" if -taken as a integer number- is equal to 0; false for every other value. (Fun fact: this is why you usually end the code by return 0)
So if(x%3) in c is equivalent to if(x%3==0) in other languages. That said, if(x%3) execute the if body when the remainder of x/3 is 0, that is when x is a multiple of 3.
In your code you have the ! before, that -as you may know- "inverts" the expression. That means that if(!(x%3)) can be read as "If the remainder of the integer division of x by 3 is not 0", or alternatively: "If x is not a multiple of 3".
So, basically, you saw it right.
Hope I helped!

How to write one line and nested 'if' statement without '?:' (is it possible?)

Is it possible to write a one line if-else statement (i.e. only using one ;) without using the ?: expression? For instance something of the form:
if (p == 1) " " else "\n";
Potential purpose could be:
cout << if (p == 1) " " else "\n";
Just curious if this is possible, don't know if there are any practical applications for this.
Thanks
You're asking "how do I do X, without using any of the tools the language provides to do X". It's silly.
And the answer's no. It's not possible.
This doesn't address the general question, but it does work for the specific example you provided.
std::cout << " \n"[(bool)(p - 1)];
Explanation:
First, a string literal (such as " \n") is an array. As such, it participates in pointer decay, and can be indexed just like any other pointer or array.
Second, an integer can be converted to a bool, and the conversion has the special property that a zero is converted to false, and anything else is converted to true. So when I subtract 1 from p, then convert it to bool, it is false if p is 1, and true otherwise.
Third, a bool can be (implicitly) converted back to an integer. false converts to 0, and true converts to 1. So converting from an int to a bool and back has the result that a 0 stays a 0, and anything else becomes a 1.
So, with those three points taken into consideration, the expression:
" \n"[(bool)(p - 1)]
results in one of these two possibilities:
" \n"[0] // a space (if p == 1)
" \n"[1] // or a newline (if p != 1)
I'd downvote this answer if I could.
You already used the two important words that are key to undestand why what you intend is not possible, but you probably haven't grasped their full meaning: Statement and expression.
The if statement (like all statements) does not yield a value, while the ?: operator is an expression that does yield a value.
Distinguishing between statements and expressions is a fundamental concept that is worth learning (check out the links in this answer and take your time!), not just for C++ but for almost all programming languages.
cout << [=]{ if (p == 1) return " "; else return "\n"; }();
Basically: no, it's not possible to do this:
cout << if (p == 1) " " else "\n";
That is exactly the purpose of ?: operator - it yields value. Some things may not be possible with if-else syntax. Example: conditional initialization. Consider:
if(p == 1)
int value = 1; //local variable!
else
int value = 0; //and so is this one!
//here 'value' is unknown
Above problem could be solved this way:
int value; //default initialization
if(p == 1)
value = 1; //assignment to already initialized variable!
else
value = 0; //and so is this!
But these two are not equal. For some types, it may result in totally different behavior, because initialization is different from assignment. ?: is a solution:
int value == (p == 1) ? 1 : 0; //'value' is initialized with value, that depends on 'p'
Do not try to do things without tools, that were designed to do that things for you.

C++ reading a sequence of integers

gooday programers. I have to design a C++ program that reads a sequence of positive integer values that ends with zero and find the length of the longest increasing subsequence in the given sequence. For example, for the following
sequence of integer numbers:
1 2 3 4 5 2 3 4 1 2 5 6 8 9 1 2 3 0
the program should return 6
i have written my code which seems correct but for some reason is always returning zero, could someone please help me with this problem.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
int x = 1; // note x is initialised as one so it can enter the while loop
int y = 0;
int n = 0;
while (x != 0) // users can enter a zero at end of input to say they have entered all their numbers
{
cout << "Enter sequence of numbers(0 to end): ";
cin >> x;
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
n = n + 1;
y = x;
}
else
{
n = 0;
}
}
cout << "longest sequence is: " << n << endl;
return 0;
}
In your program, you have made some assumptions, you need to validate them first.
That the subsequence always starts at 1
That the subsequence always increments by 1
If those are correct assumptions, then here are some tweaks
Move the cout outside of the loop
The canonical way in C++ of testing whether an input operation from a stream has worked, is simply test the stream in operation, i.e. if (cin >> x) {...}
Given the above, you can re-write your while loop to read in x and test that x != 0
If both above conditions hold, enter the loop
Now given the above assumptions, your first check is correct, however in the event the check fails, remember that the new subsequence starts at the current input number (value x), so there is no sense is setting n to 0.
Either way, y must always be current value of x.
If you make the above logic changes to your code, it should work.
In the last loop, your n=0 is execute before x != 0 is check, so it'll always return n = 0. This should work.
if(x == 0) {
break;
} else if (x > y ) {
...
} else {
...
}
You also need to reset your y variable when you come to the end of a sequence.
If you just want a list of increasing numbers, then your "if" condition is only testing that x is equal to one more than y. Change the condition to:
if (x > y) {
and you should have more luck.
You always return 0, because the last number that you read and process is 0 and, of course, never make x == (y + 1) comes true, so the last statement that its always executed before exiting the loop its n=0
Hope helps!
this is wrong logically:
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
Should be
if(x >= (y+1))
{
I think that there are more than one problem, the first and most important that you might have not understood the problem correctly. By the common definition of longest increasing subsequence, the result to that input would not be 6 but rather 8.
The problem is much more complex than the simple loop you are trying to implement and it is usually tackled with Dynamic Programming techniques.
On your particular code, you are trying to count in the if the length of the sequence for which each element is exactly the successor of the last read element. But if the next element is not in the sequence you reset the length to 0 (else { n = 0; }), which is what is giving your result. You should be keeping a max value that never gets reset back to 0, something like adding in the if block: max = std::max( max, n ); (or in pure C: max = (n > max? n : max );. Then the result will be that max value.

How can I concisely compare a single variable to many different values?

I know you can write a statement like:
if (num1 != a && num1 != b && num1 != c ..........&& num1 != z)
(do something);
But is there an easier way to compare the num1 variable to 26 other variables? Kinda like:
if (num1 != a,b,c,d,e,f,g.......)
(do something);
If a..g are contiguous constant/enum values then just use a range check.
if (num >= a && num <= g)
{
do_something();
}
else
{
do_something_else();
}
If they are non-contiguous but constant then maybe use a switch statement.
switch (num)
{
case a:
case b:
case c:
case d:
case e:
case f:
case g:
do_something();
break;
default:
do_something_else();
break;
}
otherwise if they are just arbitrary variables or expressions then you may have just have to do it with multiple tests.
You can put a, ... ,z into a std::set and then use the find method of that set to check if num1 is in there. This has logarithmic complexity, but does not allow for short-circuiting.
First of all, a good code design should not include so many sequence of conditions.
If your case is exactly the way it is, that is trying to see if a number exists in a list, where the list is actually a collection of variables. You could simply enter those numbers into the list( vector ) and perform find operation.
Store the variables in a seperate class / struck if the situation allows for that.
If your question is more about if there is a syntax in c++ to allow a smaler if statement, then perhaps make that clearer in the question.
Use std::find:
static ValueType values[] = { a, b, ... };
// ...
if ( std::find( begin( values ), end( values ), num )
== end( values ) )

isalpha(<mychar>) == true evaluates to false?

string temp is equal to "ZERO:\t.WORD\t1" from my debugger. (the first line of my file)
string temp = RemoveWhiteSpace(data);
int i = 0;
if ( temp.length() > 0 && isalpha(temp[0]) )
cout << "without true worked" << endl;
if ( temp.length() > 0 && isalpha(temp[0]) == true )
cout << "with true worked" << endl;
This is my code to check if first character of temp is a a-z,A-Z. The first if statement will evaluate to true and the 2nd to false. WHY?!?!?! I have tried this even without the "temp.length() > 0 &&" and it still evaluates false. It just hates the "== true". The only thing I can think of is that isalpha() returns != 0 and true == 1. Then, you could get isalpha() == 2 != 1. But, I have no idea if C++ is that ... weird.
BTW, I dont need to know that the "== true" is logically pointless. I know.
output was
without true worked
Compiled with CodeBlock using GNU GCC on Ubuntu 9.10 (if this matters any)
The is* functions are only guaranteed to return a non-zero value if true, NOT necessarily a 1. A typical implementation is table based, with one entry in the table for each character value, and a set of bits defining which bit means what. The is* function will just AND the right bitmask with the table value, and return that, which will only be the value 1 for whichever type happens to have been given bit position 0.
E.g.:
#define __digit 1
#define __lower 2
#define __upper 4
extern int __type_table[];
int isdigit(int c) {
return __type_table[c+1] & __digit;
}
int isalpha(int c) {
return __type_table[c+1] & (__lower | __upper);
}
int islower(int c) {
return __type_table[c+1] & __lower;
}
int isupper(int c) {
return __type_table[c+1] & __upper;
}
Where __type_table is defined as something like int __type_table[UINT_MAX+1]; and would be initialized so (for example) __type_table['0'+1] == __digit and __type_table['A'+1] == __upper.
In case you care, the '+1' part is to leave a spot at the beginning of the table for EOF (which is typically defined as -1).
isalpha doesn't return true, it returns non-zero. This is quite common for API designed for C.
Note that in the expression isalpha(ch) == true, the subexpression true is promoted to type int with value 1.
Well, the documentation suggests that it returns either zero or non-zero, not necessarily just false or true. So you'd better check (isalpha(temp[0]) != 0).
Do not isalpha(ch) == true, but !!isalpha(ch) == true