C++ IF evaluation operand with vector - c++

I know that the evaluation of operands is from left to right and for the "&&" operand if the left one is false, the right should not be evaluated! but for this line of code with a vector it does not work like this,
suppose left =1 and v.size = 1; so we do not have v[1]. because there is only v[0] in the vector
if ((left <= (v.size() -1 )) && ( v[node].Value > v[left].Value))
{
TempMin = left;
}
So i expect that the right operand not be evaluated, but it gives me the 'out of range error'.
any ideas??
EDITED
v.size () is 1 and v.size() -1 =0.
I changed to code and find the problem and I think there is a problem with VISUAL STUDIO runtime debugger. because when I just run the code everything works great, but when I debug the code line by line the IF statement does not work properly
if (left <= v.size() -1 ) // first if
if (v[node].Value > v[left].Value) // right
TempMin = left;
in this situation the first if PASS and there is an error but if I change it to
if (left < v.size() ) // first if
or
int t = v.size() - 1;
if (left < t )
everything is ok. So it seems there is problem with (v.size() -1 )!!

Possible problems:
v.size() = 0
Then v.size() - 1 is size_t and equals 18446744073709551615 (2^64 - 1). So left <= 18446744073709551615 and you get out of range.
Solution:
left + 1 <= v.size() or left < v.size() instead of left <= v.size() - 1
v[node] gives you out of range.
Solution:
Add check for node

Related

Why will my elseif statment never executed

Any idea why the else if statment will be never executed ? The value of difference is constantly changing when the program runs.
double difference = abs(reale_x[0] - reale_x[1]);
if (0 <= difference < 45) {
timer_counter += 1;
if (timer_counter == 30) {
cout << "CLICK" << '\n';
}
}
else if (difference > 50) {
timer_counter = 0;
}
That is not how comparation works in c++.
What this code
if (0 <= difference < 45) {
does is it first compares if 0 is smaller or equal to difference. It is then "replaced" by a bool value either true or false. And then a bool value (so either 1 or 0) is compared to 45. And it will always be smaller than 45. What you have there is an always true statement.
So the way you would write this if statement is
if (difference >= 0 && difference < 45){
Note that because of your else if statement it will not execute if the difference is >44 and <51
if (0 <= difference < 45) will be executed as if ((0 <= difference) < 45), which will be either 0<45 or 1<45 and will always be true. That's why the else part is not getting executed.
in mathematics, we see and write 0 <= x < 45 or something like that to define the range of the variable x. But in order to tell the computer the same thing, you have to tell more clearly. Saying, to have to tell the compiler, that the value of x is greater than or equal to zero and at the same time, that value will be less than 45, and you can tell the compiler by this statement: difference >= && difference < 45 . the && is an 'AND' operator in most of the languages.

C++ return statement not behaving as expected

I have the following C++ code:
return lineNum >= startLineNum
&& lineNum <= startLineNum + lines.size() - 1;
Here, lineNum is an int, startLineNum is an int, lines is a std::vector<std::string>, and lines.size() is of type size_t.
When lineNum is 2, startLineNum is 0, and lines.size() is 0, the code returns true even though false was expected. These values were the values displayed in the debugger.
Even after adding parentheses where possible:
return ((lineNum >= startLineNum)
&& (lineNum <= (startLineNum + lines.size() - 1)));
the code still incorrectly returns true.
When I refactor the code into this form:
int start = startLineNum;
int end = startLineNum + lines.size() - 1;
return lineNum >= start && lineNum <= end;
it now returns false as expected.
What is going on here? I have never come across this kind of strangeness before.
lines.size() is more than likely an unsigned type. (If lines is a std::vector for example it's certainly unsigned.)
So due to the rules of argument promotion, and the fact that the terms in
startLineNum + lines.size() - 1;
are grouped from left to right, they are all converted to unsigned types.
This means that 0 + 0 - 1 is std::numeric_limits<decltype(lines.size())>::max() - a large number indeed, and lineNum is most likely less than it.
The rule of thumb: never use a negative when working with unsigned types, unless you really know what you're doing.
In your case, restate the problem to
lineNum < startLineNum + lines.size()
My guess would be that
lineNum <= startLineNum + lines.size() - 1;
is all unsigned types. linenum is 2, the other two are 0, and 0-1 in unsigned arithmetic is something VERY large (if 4 byte something above 4 billion).
Do instead
lineNum + 1 <= startLineNum + lines.size();
and all should be fine.

count consecutive 1's in binary

I am writing code in Hackerrank. And recently the problem said, convert decimal to base 2 and then count the max consecutive 1's in the binary number. And first I come with following solution. It works fine. But I do not understand the counting part of it, even though I wrote it.
The code is
int main(){
int n,ind=0, count=0, mmax=0;
char bin[100];
cin >> n;
while(n){
if(n%2==0) {
bin[ind]='0';
n = n / 2;
ind = ind + 1;
}
else if(n%2==1) {
bin[ind]='1';
n = n / 2;
ind = ind + 1;
}
}
for(int i=0; i<=(ind-1); i++){
if(bin[i] == '1' && bin[i+1] == '1'){
count++;
if(mmax < count)
mmax = count;
}
else
count=0;
}
cout << mmax + 1 << endl;
return 0;
}
In the above code, I guess that variable mmax will give me the max consecutive number of 1's but it gives me value that has (max consecutive - 1), So I just wrote like that and submitted the code. But I am curious about. why it is working that way. I am little bit of confused the way that code works like this.
Thanks
Lets say you have this binary sequence:
11110
Your code will compare starting from the first and second:
|11|110 1 && 1 -> max = 1
1|11|10 1 && 1 -> max = 2
11|11|0 1 && 1 -> max = 3
111|10| 1 && 0 -> max = 3
you can see, that although there are 4 1's you only do 3 comparisons, so your max will always be -1 of the actual max. You can fix this by adding mmax += 1 after your for loop.
Just a little bit of trace using small example will show why.
First, lets say there is only 1 '1' in your array.
Since you require both the current position and your next position to be '1', you will always get 0 for this case.
Let's say I have "11111". At the first '1', since next position is also '1', you increment count once. This repeats until 4th '1' and you increment your count 4 times in total so far. When you reach 5th '1', your next position is not '1', thus your count stops at 4.
In general, your method is like counting gaps between fingers, given 5 fingers, you get 4 gaps.
Side note: your code will fail for the case when there is no '1' in your array.

What are the base cases for Coin Change using Recursion?

I am basically trying to solve the coin change problem through recursion and here is what i have so far -:
#include<iostream>
#include<conio.h>
using namespace std;
int a[]={1,2,5,10,20,50,100,200},count=0;
//i is the array index we are working at
//a[] contains the list of the denominations
//count keeps track of the number of possibilities
void s(int i,int sum) //the function that i wrote
{
if (!( i>7 || sum<0 || (i==7 && sum!=0) )){
if (sum==0) ++count;
s(i+1,sum);
s(i,sum-a[i]);
}
}
int c(int sum,int i ){ //the function that I took from the algorithmist
if (sum == 0)
return 1;
if (sum < 0)
return 0;
if (i <= 0 && sum > 0 )
return 1;
return (c( sum - a[i], i ) + c( sum, i - 1 ));
}
int main()
{
int a;
cin>>a;
s(0,a);
cout<<c(a,7)<<endl<<count;
getch();
return 0;
}
The first function that is s(i,sum) has been written by me and the second function that is c(sum,i) has been taken from here - (www.algorithmist.com/index.php/Coin_Change).
The problem is that count always return a way higher value than expected. However, the algorithmist solution gives a correct answer but I cannot understand this base case
if (i <= 0 && sum > 0 ) return 1;
If the index (i) is lesser than or equal to zero and sum is still not zero shouldn't the function return zero instead of one?
Also I know that the algorithmist solution is correct because on Project Euler, this gave me the correct answer.
I guess that your problem is "Assuming that I have unlimited support of coins, on how many ways can I change the given sum"?
The algoritimists solution you gave assumes also, that the smallest denomination is 1. Otherwise it will won't work correctly.
Now your question:
if (i <= 0 && sum > 0 ) return 1;
Notice, that the only possibility that i<0 is that you called it with this value - no recursive call will be made with negative value of i. Such case (i<0) is an error so no result is proper (maybe assertion or exception would be better).
Now if i=0, assuming that at index 0 there is coin of value 1 means that there is only one way to exchange sum with this denomination - give sum coins of value 1. Right?
After a moment of thought I found out how to remove assumption that a[0] == 1. Change
if (i <= 0 && sum > 0 ) return 1;
into
if (i <= 0 && sum > 0 ) return sum % a[0] == 0 ? 1 : 0;
I believe the algorithm to be biased towards the choice of denominations, and assumes that there will be only one coin of the smallest denomination. Consider as a counter example of the correctness that there was no 2 coins, just 1,5,... And that the target to return was 4:
(4,1)
(-1,1) -> cut, sum<0 a[1]==5
(4,0) -> i==0 => 1
Either that or you misimplemented the algorithm (can there be an off by one error? Could it be i<0, or the original array be 1-based?)

Unexpected output of C code

What would be the output of this program ?
#include<stdio.h>
#include<conio.h>
void main()
{
clrscr();
int x=20,y=30,z=10;
int i=x<y<z;
printf("%d",i);
getch();
}
Actually i=20<30<10, so the condition is false and the value of i should be 0 but i equals 1. Why?
This int i=x<y<z; doesn't work the way you intended.
The effect is int i=(x<y)<z;, where x<yis evaluated first, and the value true is then compared to z.
Pascal points out below that in C the result of the comparison is 1 instead of true. However, the C++ true is implicitly converted to 1 in the next comparison, so the result is the same.
The comparison operators don't work like that. Your program is equivalent to:
i = (x < y) < z;
which is equivalent to:
i = (x < y);
i = i < z;
After the first operation, i == 1. So the second operation is equivalent to:
i = 1 < 10;
You need to rewrite your statement as:
i = (x < y) && (y < z);
The < operator has left-to-right associativity. Therefore x<y<z will do (x<y)<z. The result of the first parenthesis is 1, 1 is smaller than 10, so you'll get 1.
That's not how it works. It's better to see with parenthesis:
int i = (x<y)<z;
Now, first x<y is evaluated. It's true, 20<30, and true is 1 as an integer. 1<z is then true again.
Its precedence is from left to right. Thats is why it is like
20<30 = true
1<10 TRUE
SO FINALLY TRUE
Actually < is left-associative, so first, 20<30 is evaluated (giving 1 usually), then 1 is less than 10.
The output of "1" is correct. This is evaluated as (20<30) < 10, which is 1 < 10, which is 1.
The problem is that you are comparing a boolean value to an integer value which in most cases doesn't make sense.
< is evaulated from left to right, so 20<30 is true, or one, which is less than 10.
The operator < associates from left to right.
So x < y < z is same as ( x < y ) < z
Your expression evaluates as:
( x < y ) < z
= ( 20 < 30 ) < 10
= ( 1 ) < 10
= 1