What does these following statement do?
The output from gcc is: 1 101.
Can anyone explain why so is the case?
int a = 100, b = 108, c = 2;
a += b ? c = 1 : c = 0;
cout << c << " " << a;
It's equivalent to:
a += (b ? (c=1) : (c=0));
Expanding out:
a = a + (b ? (c=1) : (c = 0)); // if (b!=0) then let c=1, else let c=0
Filling in for a and b:
a = 100 + (108 ? (c=1) : (c = 0));
Since 108 is not a "false" (0) expression, then the assignment of c=1 is executed. A side effect of an assignment is that the assignment is equal to that assigned value. And the result of that assignment is added to a:
a = 100 + (c=1);
Which is equivalent to:
t = (c = 1); // t is 1
a = 100 + t;
And thus, since t is 1:
a = 100 + 1;
Add parenthesis (and space) so you can see what is happening:
int a = 100,b=108,c=2;
a += ((b != 0) ? c=1 : c=0);
cout<<c<<" "<<a;
Now replace with words (no longer legal C/C++):
int a = 100,b=108,c=2;
a += (if b != 0 then result=c=1 else result=c=0);
cout<<c<<" "<<a;
Then separate:
if b != 0 then result=c=1 else result=c=0
a += result
Since b != 0:
result = c = 1
a += result
Lets expand
a = a + (b ? c = 1 : c = 0);
since b = 108 which evaluates to true, the expression c = 1 is evaluated.
Now, the assignment c = 1 is successfull, so that returns 1, and the expression becomes
a = a + 1
Therefore, in the end, the values are c = 1 and a = 101
int a = 100, b = 108, c = 2;
a += b ? c = 1 : c = 0;
this is equivalent to
a = a + (b ? c = 1 : c = 0);
This (?:) is ternary condition operator which work like if-else condition.
if condition is true it will run first otherwise second.
(b ? c = 1 : c = 0;)
if true ^^^^^
if false ^^^^^^
as b=108 which will give TRUE, so it will make c=1 and return c;
now
a = a + 1;
this will make a = 101
? is the ternary operator. It's logically equivalent to the following:
int a = 100,b=108,c=2;
if(b) {
c = 1;
} else {
c = 0;
}
a+=c;
// c is 1 because b is true (nonzero)
// a is a+c = 101
Related
I am trying to solve ax + by = n.
When I put n = 7, it solves the equation correctly as X = 2 and Y = 1.
But when I put n = 1, it does not solve the equation. Even though, this equation has valid integer solution, X = 17, Y = -11. here is my full program.
#include <iostream>
using namespace std;
void PrintXY(int a, int b, int n)
{
for (int i = 0; i * a <= n; i++) {
if ((n - (i * a)) % b == 0) {
cout << "x = " << i << ", y = "
<< (n - (i * a)) / b;
return;
}
}
cout << "No solution";
}
int main()
{
int a = 2, b = 3, n = 1;
PrintXY(a, b, n);
return 0;
}
Output when n = 7:
x = 2, y = 1
Output when n = 1:
No solution
Reasoning.
2*(2) + 3*(1) - 7 = 4 + 3 - 7 = 0
2*(17) + 3*(-11) - 1 = 34 - 33 - 1 = 0
Both equations solve to give 0. But what is wrong in my program that is causing it to give "No Solution".
The problem is with the termination condition:
i*a<=n
This(n>=a*i) need not be true, and is especially not true in case of the solution (ie X=17, Y=-11). Which seems reasonable - Without any bounds(limits) on the answer(either X or Y) , how would you find the solution to a linear equation(with an infinite possible range) in a closed for loop ?
Consider the following
int main() {
int a = 8;
int b = 10;
while (true) {
if (a /= 2 && b < 12) {
b++;
std::cout << b << std::endl;
}
else break;
}
return 0;
}
Now c++ is not my main language, but how does c++ evaluate this if statement?
In this case, when b>=12, the compiler throws the "division by zero" exception, but why?
Now if i wrap the states in parentheses i do not get the exception.
if( (a /= 2) && (b < 12))
Does this have something to do with how c++ evaluates the statements?
If evaluation is not the problem:
I am aware of that
a = (a/2 && b<12)
would not hold either.
P Λ Q does not hold for P Λ ¬Q but the state of P should not be affected? Why is it P gets blamed instead of ¬Q?
if (a /= 2 && b < 12)
is the same as:
if (a /= (2 && b < 12))
so:
2 is evaluated, which is converted to true in the context of an operand to &&. This does not trigger short-circuit evaluation so we continue...
b < 12, which in the case you're talking about is false
So 2 && b < 12 evaluates to false overall
a /= 2 && b < 12 is therefore equivalent to a /= false here, which is equivalent to a /= 0.
I came accross this expression, and can't understand the meaning of line 3 in the following snippet:
int A=0, B=0;
std::cout << A << B << "\n"; // Prints 0, 0
A += B++ == 0; // how does this exp work exactly?
std::cout << A << B << "\n"; // Prints 1, 1
A adds B to it, and B is Post incremented by 1, what does the "==0" mean?
Edit:
Here's the actual code:
int lengthOfLongestSubstringKDistinct(string s, int k) {
int ctr[256] = {}, j = -1, distinct = 0, maxlen = 0;
for (int i=0; i<s.size(); ++i) {
distinct += ctr[s[i]]++ == 0; //
while (distinct > k)
distinct -= --ctr[s[++j]] == 0;
maxlen = max(maxlen, i - j);
}
return maxlen;
}
B++ == 0
This is a boolean expression resulting in true or false. In this case the result is true, true is then added to A. The value of true is 1 so the (rough) equivalent would be:
if(B == 0)
A += 1;
++B;
Note that this isn't particulary good or clear to read code and the person who wrote this should be thrown into the Gulags.
Lets break this expression into pieces: A += value, whereas value = B++ == 0. As later cout suggests, value == 1. Why is that? Here is why: value is result of comparison of B++ and 0, but ++ (increment) operation, when written after operand, is being processed after the comparison, i.e. if you write A += ++B == 0 the later cout should (and does) print 0, 1.
I have this code (tsp problem) that works for the 2-opt optimization and i'd like to change it for a 3-opt optimization. I know i must add a for, but don't really understand the range of the third for. Can you help me?
double bestDecrement = tsp.infinite;
// intial and final position are fixed (initial/final node remains 0)
for ( uint a = 1 ; a < currSol.sequence.size() - 2 ; a++ )
{
int h = currSol.sequence[a-1];
int i = currSol.sequence[a];
for ( uint b = a + 1 ; b < currSol.sequence.size() - 1 ; b++ )
{
int j = currSol.sequence[b];
int l = currSol.sequence[b+1];
double neighDecrement = - tsp.cost[h][i] - tsp.cost[j][l] + tsp.cost[h][j] + tsp.cost[i][l] ;
if ( neighDecrement < bestDecrement )
{
bestDecrement = neighDecrement;
move.from = a;
move.to = b;
}
}
}
Basically you are looking for 3 edges to remove and then reinsert. So for example:
for ( uint a = 1 ; a < currSol.sequence.size() - 3 ; a++ )
...
for ( uint b = a + 1 ; b < currSol.sequence.size() - 2 ; b++ )
...
for ( unit c = b + 1 ; c < currSol.sequence.size() - 1 ; c++)
...
The trickier part is determining the new costs, since there are a few feasible reinsertions (as opposed to just one in 2-opt).
I was just writing an improved linear version of a recursive Fibonacci algorithm, and realized that my boolean expressions look really bad and unreadable. Is there a cleaner way to do what I'm trying to do?
int fibonacci(int num) {
if (num <= 1)
return num;
// starts looking ugly here
int a = intExists(num-1);
int b = intExists(num-2);
bool aAndB = (a != -1 && b != -1);
bool justA = (a != -1 && b == -1);
bool justB = (a == -1 && b != -1);
int number = 0;
if (aAndB)
number = (a + b);
else if (justA)
number = (a + fibonacci(num - 2));
else if (justB)
number = (fibonacci(num-1) + b);
else
number = (fibonacci(num - 1) + fibonacci(num - 2));
map.push_back(Pair(num, number));
return number;
}
Thanks
If you're talking about:
bool aAndB = (a != -1 && b != -1);
then I would say, "no."
This code looks perfectly expressive to me. aAndB is initialized at the moment it comes in to being, and the conditions are very clear. This might look a bit odd when you're first starting out in C++, but before you know it it will be second nature and other constructs will seem silly.
One thing I would suggest is to make aAndB const if you don't intend to change it:
const bool aAndB = (a != -1 && b != -1);
This is even more expressive.
It also might give the compiler an additional opportunity to optimize your code.
Remember -- write code for humans to understand. Not for computers to understand.
Why don't you make a and b as bools and assign those as true if a == -1 and false otherwise. Then, the expressions will become easier to handle.
Could do a switch statement to clean up the if else statements a little. Other than that just add comments
You could rewrite it to use conditional branching, like this:
int fibonacci(int num) {
if (num <= 1)
return num;
int a = intExists(num-1);
int b = intExists(num-2);
const bool isA = (a != -1); // change in the definition
const bool isB = (b != -1); // change in the definition
int number = 0;
if (isA && isB)
number = (a + b);
else if (isA) // conditionnal branching
number = (a + fibonacci(num - 2));
else if (isB) // conditionnal branching
number = (fibonacci(num-1) + b);
else
number = (fibonacci(num - 1) + fibonacci(num - 2));
map.push_back(Pair(num, number));
return number;
}
I'm assuming that intExists(n) looks up map and if finds n in there, returns fibonacci(n) else it returns -1. Then you could do this:
int fibonacci(int num) {
if (num <= 1)
return num;
int a = intExists(num-1);
int b = intExists(num-2);
if (a == -1) // if a wasn't found, then compute it
a = fibonacci(num-1);
if (b == -1) // if b wasn't found, then compute it
b = fibonacci(num-2);
int number = a + b;
map.push_back(std::make_pair(num, number));
return number;
}
Bonus:
Here is another completely different implementation of fibonnacci() based on Binet's formula:
#include <cmath>
int fibonacci(int n) {
static const double e1 = 1.6180339887498948482045868343656; // = (1 + sqrt(5)) / 2
static const double e2 = -0.61803398874989484820458683436564; // = (1 - sqrt(5)) / 2
static const double c = 0.44721359549995793928183473374626; // = 1 / sqrt(5);
double f = c * (std::pow(e1, n) - std::pow(e2, n));
return static_cast<int>(f + 0.5);
}
int main() {
for (int n = 1; n < 15; ++n)
std::cout << fibonacci(n) << ' ';
}
It outputs:
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Plain C++ code is clean enough:
bool a = intExists(num-1);
bool b = intExists(num-2);
if (a && b) {
//
} else if (a) {
//
} else if (b) {
//
} else {
//
}
int a = intExists(num-1);
int b = intExists(num-2);
bool aAndB = (a != -1 && b != -1);
bool justA = (a != -1 && b == -1);
bool justB = (a == -1 && b != -1);
Quick look into the approach you took. Under what circumstances can justB be true? (Hint: never)
That should help you simplify your approach, although there are better approaches than memoization.
Changing intExists to return boolean values, you can do a switch-case statements like that:
bool a = intExists(num-1);
bool b = intExists(num-2);
switch ((a << 1) + b) {
default: // none exists
case 1: // only b exist
case 2: // only a exist
case 3: // both exists
}
The rationale is to transform those booleans in a binary number
A slightly drastic rewrite is to let an external function handle the lookup table.
That way you don't need to care about more than one value at a time.
This one uses map so I didn't have to write so much in order to test it, but it should be easy enough to adapt:
std::map<int, int> table;
int fibonacci(int num);
int value(int num)
{
int result = table[num];
if (!result)
{
result = fibonacci(num);
table[num] = result;
}
return result;
}
int fibonacci(int num)
{
if (num <= 2)
return 1;
return value(num - 1) + value(num - 2);
}