boost lambda for_each / transform puzzle - c++

Does anybody know why
vector<int> test(10);
int a=0;
for_each(test.begin(),test.end(),(_1+=var(a),++var(a)));
for_each(test.begin(),test.end(),(cout << _1 << " "));
cout << "\n"
Gives : "0 1 2 3 4 5 6 7 8 9"
but
transform(test.begin(),test.end(),test.begin(), (_1+=var(a),++var(a)));
...(as before)
Gives : "1 2 3 4 5 6 7 8 9 10"
?

Comma operator evaluates left to right, so the result of the
_1+=var(a), ++var(a)
is ++var(a), which you'll store using the transform version.
for_each:
_1 += var(a) is evaluated, updating your sequence (via the lambda _1), then ++var(a) is evaluated, but this has no effect on your sequence.
transform:
_1+=var(a) is evaluated, updating your sequence (just like before), then ++var(a) is evaluated, this also gives the result of the whole expression, then that is used to update your sequence again (via the transform)

Essentially, in the for_each you provide a function with a side-effect, while in the transform, your use the returnvalue of a function.
In your case, you reuse the same function. Since operator += happens to have a return value, this is the one used as a result of the transformation.

transform(test.begin(),test.end(),test.begin(),
(_1+=var(a),++var(a)));
This will translate to
int doit(int & elem) {
elem += a;
return ++a;
}
for each elem : elem = doit(elem);
Starting with a=0 will result in 1 in the first run. We are incrementing a 10 times, so we will get 10 in the last run.
for_each(test.begin(),test.end(),(_1+=var(a),++var(a)));
This will translate to
void doit(int & elem) {
elem += a;
++a;
}
for each elem : doit(elem);
Starting with a=0, we will get 0 in the first run. We increment a 10 times, but assign it just before incrementing. Thus the last number is 9.
I hope it's clear now with the translation to ordinary functions what those two do.

Related

Why adding "variable + 1" doesn't increment its value by one for every loop in a for loop? (C++)

I'm having a hard time understanding why using a increment operator in a for loop in C++ has a different result than doing 'variable' + 1. The variable in the second case simply isn't remembered after each iteration of the loop:
Take the following code:
#include <iostream>
int main(){
int a{0};
for (int i = 0; i < 5; i++){
std::cout << ++a;
}
return 0;
}
It outputs as expected:
12345
However, if I instead replace ++a with a + 1:
#include <iostream>
int main(){
int a{0};
for (int i = 0; i < 5; i++){
std::cout << a + 1;
}
return 0;
}
I get:
11111
Even if I make the 'a' variable static:
static int a{0};
It still outputs 11111.
Why doesn't 'a + 1' preserve its value after every loop? What would I need to do if I wanted to preserve its value after every iteration without using ++ (for instance, with another operation like a * 2)?
Why doesn't 'a + 1' preserve its value after every loop?
a + 1 is an expression that doesn't assign anything to a. That is a is not affected in any way. This means when you do just a + 1, the value of a is still 0(the old value).
On the other hand ++a has the same effect as:
v---------->assignment done here implicitly
a = a+1
In the above expression ++a, the value of is incremented by 1 so that the new value of a is now 1.
++a is equivalent to the assignment a= a + 1 (or a+= 1). The expression a + 1 alone does not modify a.
C++ will allow you to write std::cout << (a= a + 1);.
a++ is not the same thing as a+1 but as a=a+1.
What's the difference?
Well:
a+1 contains the value, which is one higher than the value of a.
a=a+1 means that, in top of this, this value gets assigned to the variable a, which means something like "replace a by its value plus one".
This gives following possibilities (I also show the difference between a++ and ++a):
int a=3;
cout<<a+1; // output : 4. Value of 'a' equals 3.
cout<<a+1; // output : 4. Value of 'a' equals 3.
cout<<a+1; // output : 4. Value of 'a' equals 3.
int a=3;
cout<<a++; // output : 3. Value of 'a' becomes 4 after having shown it on screen.
cout<<a++; // output : 4. Value of 'a' becomes 5 after having shown it on screen.
cout<<a++; // output : 5. Value of 'a' becomes 6 after having shown it on screen.
int a=3;
cout<<++a; // output : 4. Value of 'a' becomes 4 before showning it on screen.
cout<<++a; // output : 5. Value of 'a' becomes 5 before showning it on screen.
cout<<++a; // output : 6. Value of 'a' becomes 6 before showning it on screen.
Conceptually, the built-in arithmetic operators like + and * evaluate their operands, perform the respective operation with the thusly obtained values, and create a temporary object that contains the result.
The operands, one of which is your a, are only read from, not written to. That is more obvious when you consider that + is commutative, that is, its operands can be swapped without affecting the result: a+1 is by definition the same as 1+a, and clearly you cannot write anything back to the immediate value 1.
Generally, as you certainly know, = is used in C and C++ to write a value to a variable. C, and by means of ancestry also C++, provide shortcuts to write back the result of certain operations to one of their operands: it's the combination of the operator and the assignment =, for example a += 1. Like all assignments, this one is an expression (that is, it has a value) which has the value of the variable after the operation and assignment. Like all other expressions, you can use it as a subexpression, even though that's not very common: cout << (a += 1); would achieve the desired effect (the parentheses are necessary because assignment has about the lowest operator precedence). Because incrementing (and decrementing) by one is so very common, C and C++ have a shortcut for the shortcut: ++a is the same as a+=1, so that one would typically write cout << ++a; (as a side effect obviating the need for parentheses).

Why should you include more than one value in a return statement?

I've seen instances where someone would use return statements with multiple values. For example: return 8, 10, 6; As far as I know, only one of these values will actually be returned. What is the benefit of using return this way?
Specifically, this question appears on my homework.
The statement: return 2 * 3 + 1, 1 + 5; returns the value ____.
I know it would always return 6, so why would I ever write it like this?
Forgive me if this is a simple question. I am still somewhat new to programming.
The statement return 2 * 3 + 1, 1 + 5; returns the value 6.
This the trick of comma operator in C++. You can read more about it here:
https://en.cppreference.com/w/cpp/language/operator_other
A comma operator is basically a list of expressions separated by commas, they will be evaluated from left to right, and the result of the last item will be treated as the result of the whole comma operator.
Here is a simple example demonstrating how comma operator works.
int foo() {
int i = 1;
return i += 2, i++, i + 5; // This is a comma operator with three items
// i += 2 will be evaluated first, then i == 3
// i++ will be evaluated second, then i == 4
// i + 5 will be evaluate last, and the result is 9
// the result of the last item is returned by the return statement
}
int main() {
std::cout << foo();
return 0;
}
This code prints 9.
When you do this you are avoiding using math in your function block and this make your function like working 3 time and result would be the one you want

concatenate two vectors for divide and conquer algorithm c++

I'm trying to get a divide and conquer algorithm working that returns a vector, and since it's a divide and conquer algorithm it obviously needs to run more than one instance at a time. The problem is when it comes down to the return portion.
Right now I have:
vector<MyObject> MyProgram(...){
...Code that's not important...
return MyProgram(...) + MyProgram(...);
}
unfortunately apparently I can't just use the + operand. I know that you can concatenate vectors by inserting one into the other, or copying one into the other, but then MyProgram would be getting called one after the other, not simultaneously.
I'm literally guessing that this is what you're trying to accomplish, but it is conjecture at best, so let me know whether this answer should be deleted due to being inapplicable.
The following defines a function that returns an empty vector if the argument is zero. Otherwise is returns a vector of N instances of the value N concatenated with the function evaluated at N-1. The concatenation is done asynchronously via a separate thread, thereby giving you the potential for concurrency.
#include <iostream>
#include <vector>
#include <future>
std::vector<unsigned int> MyFunction(unsigned arg)
{
std::vector<unsigned int> result;
if (arg == 0)
return result;
auto fc = std::async(std::launch::async, MyFunction, arg-1);
for (unsigned int i=0; i<arg; ++i)
result.emplace_back(arg);
std::vector<unsigned int> theirs = fc.get();
result.insert(result.begin(), theirs.begin(), theirs.end());
return result;
}
int main()
{
std::vector<unsigned int> res = MyFunction(8);
for (auto x : res)
std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
Output
1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8
Each miniature sequence is generated on a separate thread except the first one, in this case the sequence of 8's, generated on the primary thread.
Anyway, I hope it gives you some ideas.
Use a wrapper. Now just add an overloaded operator+ to that class.
Such a Wrapper can look like this:
class Wrapper
{
public:
Wrapper(const vector<MyObject>& _vec) : vec(_vec) {}
Wrapper operator+(Wrapper& rhs)
{
vector<MyObject> tmp(vec);
tmp.insert(tmp.end(), rhs.vec.begin(), rhs.vec.end());
return Wrapper(tmp);
}
operator const vector<MyObject>&(){return vec;}
private:
vector<MyObject> vec;
};
Your function would then be like:
Wrapper MyProgram(...){
...Code that's not important...
return MyProgram(...) + MyProgram(...);
}
Please check the comments for important warnings about your current design.

Recursive Formula

First, yes it's HW - really tried but not sure of something so ill be happy if you will help me:)
I have this code:
void func(int A[], int start, int n)
{
int p = n/2;
if ( 1 < n )
{
func(A, start, p);
func(A, start + p, n-p);
for (i=0; i<n; i++)
cout << A[start+i];
}
}
func(A, 0, n);
I need to give this code a recusive formula.
What I did was - first recursion call is T(n/2).
Second - this is the problem! really confuse with adding the 'p'...is that
T(n/2) too??
Three - for is running on theta(n)
and the outside recursion call is T(n)...
Can you help me get to the final formula??
Thanks
If I read it right, you want the recurrence for the run time complexity.
For n > 1, you recur with parameter floor(n/2) and with parameter n-floor(n/2), and after that you output n items. Thus you have
T(n) = T(cost of first recursive call) + T(second rec. call) + extra work
which you should now bring into a form suitable to apply the master theorem.
This is either a trick question or you misread the question. What you have is a recursive formula. Do you need to switch this formula from C++ to more traditional math notation? Do need to find a non-recursive algorithm? In your answer to the question, what is T? The term formula does not really apply here because nothing gets computed. This is a void function that never modifies the given array. All that happens is some things elements from the array get put on the screen in some order.
I would start by tracing an example to understand what is going on.
Lets say A = {1,2,3,4} Then 'func(A, 0,4)' is:
tracing func(A,0,4) :
p = 2
func(A,0,2)
func(A,2,2)
cout << 1 2 3 4
tracing func(A,0,2) :
p = 1 //start=0; n=2
func(A,0,1)
func(A,1,1)
cout << 1 2
tracing func(A,2,2) :
p = 1 //start=2; n=2
func(A,2,1)
func(A,3,1)
cout << 3 4
tracing func(A,2,1) :
p = 0 //start=0; n=1
func(A,0,0)
func(A,0,1)
cout << 1
tracing func(A,3,1) :
p = 0 //start=3; n=1
func(A,3,0)
func(A,3,1)
cout << 3
tracing func(A,2,1) :
p = 0 //start=0; n=1
func(A,0,0)
func(A,0,1)
cout << 1
At this point I'm going to stop because this is your homework problem. You can finish it from here.

What is the "-->" operator in C++?

After reading Hidden Features and Dark Corners of C++/STL on comp.lang.c++.moderated, I was completely surprised that the following snippet compiled and worked in both Visual Studio 2008 and G++ 4.4.
Here's the code:
#include <stdio.h>
int main()
{
int x = 10;
while (x --> 0) // x goes to 0
{
printf("%d ", x);
}
}
Output:
9 8 7 6 5 4 3 2 1 0
I'd assume this is C, since it works in GCC as well. Where is this defined in the standard, and where has it come from?
--> is not an operator. It is in fact two separate operators, -- and >.
The conditional's code decrements x, while returning x's original (not decremented) value, and then compares the original value with 0 using the > operator.
To better understand, the statement could be written as follows:
while( (x--) > 0 )
Or for something completely different... x slides to 0.
while (x --\
\
\
\
> 0)
printf("%d ", x);
Not so mathematical, but... every picture paints a thousand words...
That's a very complicated operator, so even ISO/IEC JTC1 (Joint Technical Committee 1) placed its description in two different parts of the C++ Standard.
Joking aside, they are two different operators: -- and > described respectively in §5.2.6/2 and §5.9 of the C++03 Standard.
x can go to zero even faster in the opposite direction in C++:
int x = 10;
while( 0 <---- x )
{
printf("%d ", x);
}
8 6 4 2
You can control speed with an arrow!
int x = 100;
while( 0 <-------------------- x )
{
printf("%d ", x);
}
90 80 70 60 50 40 30 20 10
;)
It's equivalent to
while (x-- > 0)
x-- (post decrement) is equivalent to x = x-1 (but returning the original value of x), so the code transforms to:
while(x > 0) {
x = x-1;
// logic
}
x--; // The post decrement done when x <= 0
It's
#include <stdio.h>
int main(void) {
int x = 10;
while (x-- > 0) { // x goes to 0
printf("%d ", x);
}
return 0;
}
Just the space makes the things look funny, -- decrements and > compares.
The usage of --> has historical relevance. Decrementing was (and still is in some cases), faster than incrementing on the x86 architecture. Using --> suggests that x is going to 0, and appeals to those with mathematical backgrounds.
Utterly geek, but I will be using this:
#define as ;while
int main(int argc, char* argv[])
{
int n = atoi(argv[1]);
do printf("n is %d\n", n) as ( n --> 0);
return 0;
}
while( x-- > 0 )
is how that's parsed.
One book I read (I don't remember correctly which book) stated: Compilers try to parse expressions to the biggest token by using the left right rule.
In this case, the expression:
x-->0
Parses to biggest tokens:
token 1: x
token 2: --
token 3: >
token 4: 0
conclude: x-- > 0
The same rule applies to this expression:
a-----b
After parse:
token 1: a
token 2: --
token 3: --
token 4: -
token 5: b
conclude: (a--)-- - b
This is exactly the same as
while (x--)
Anyway, we have a "goes to" operator now. "-->" is easy to be remembered as a direction, and "while x goes to zero" is meaning-straight.
Furthermore, it is a little more efficient than "for (x = 10; x > 0; x --)" on some platforms.
This code first compares x and 0 and then decrements x. (Also said in the first answer: You're post-decrementing x and then comparing x and 0 with the > operator.) See the output of this code:
9 8 7 6 5 4 3 2 1 0
We now first compare and then decrement by seeing 0 in the output.
If we want to first decrement and then compare, use this code:
#include <stdio.h>
int main(void)
{
int x = 10;
while( --x> 0 ) // x goes to 0
{
printf("%d ", x);
}
return 0;
}
That output is:
9 8 7 6 5 4 3 2 1
My compiler will print out 9876543210 when I run this code.
#include <iostream>
int main()
{
int x = 10;
while( x --> 0 ) // x goes to 0
{
std::cout << x;
}
}
As expected. The while( x-- > 0 ) actually means while( x > 0). The x-- post decrements x.
while( x > 0 )
{
x--;
std::cout << x;
}
is a different way of writing the same thing.
It is nice that the original looks like "while x goes to 0" though.
There is a space missing between -- and >. x is post decremented, that is, decremented after checking the condition x>0 ?.
-- is the decrement operator and > is the greater-than operator.
The two operators are applied as a single one like -->.
It's a combination of two operators. First -- is for decrementing the value, and > is for checking whether the value is greater than the right-hand operand.
#include<stdio.h>
int main()
{
int x = 10;
while (x-- > 0)
printf("%d ",x);
return 0;
}
The output will be:
9 8 7 6 5 4 3 2 1 0
C and C++ obey the "maximal munch" rule. The same way a---b is translated to (a--) - b, in your case x-->0 translates to (x--)>0.
What the rule says essentially is that going left to right, expressions are formed by taking the maximum of characters which will form a valid token.
Actually, x is post-decrementing and with that condition is being checked. It's not -->, it's (x--) > 0
Note: value of x is changed after the condition is checked, because it post-decrementing. Some similar cases can also occur, for example:
--> x-->0
++> x++>0
-->= x-->=0
++>= x++>=0
char sep = '\n' /1\
; int i = 68 /1 \
; while (i --- 1\
\
/1/1/1 /1\
/1\
/1\
/1\
/1\
/ 1\
/ 1 \
/ 1 \
/ 1 \
/1 /1 \
/1 /1 \
/1 /1 /1/1> 0) std::cout \
<<i<< sep;
For larger numbers, C++20 introduces some more advanced looping features.
First to catch i we can build an inverse loop-de-loop and deflect it onto the std::ostream. However, the speed of i is implementation-defined, so we can use the new C++20 speed operator <<i<< to speed it up. We must also catch it by building wall, if we don't, i leaves the scope and de referencing it causes undefined behavior. To specify the separator, we can use:
std::cout \
sep
and there we have a for loop from 67 to 1.
Instead of regular arrow operator (-->) you can use armor-piercing arrow operator: --x> (note those sharp barbs on the arrow tip). It adds +1 to armor piercing, so it finishes the loop 1 iteration faster than regular arrow operator. Try it yourself:
int x = 10;
while( --x> 0 )
printf("%d ", x);
Why all the complication?
The simple answer to the original question is just:
#include <stdio.h>
int main()
{
int x = 10;
while (x > 0)
{
printf("%d ", x);
x = x-1;
}
}
It does the same thing. I am not saying you should do it like this, but it does the same thing and would have answered the question in one post.
The x-- is just shorthand for the above, and > is just a normal greater-than operator. No big mystery!
There are too many people making simple things complicated nowadays ;)
Conventional way we define condition in while loop parenthesis"()" and terminating condition inside the braces"{}", but this -- & > is a way one defines all at once.
For example:
int abc(){
int a = 5
while((a--) > 0){ // Decrement and comparison both at once
// Code
}
}
It says, decrement a and run the loop till the time a is greater than 0
Other way it should have been like:
int abc() {
int a = 5;
while(a > 0) {
a = a -1 // Decrement inside loop
// Code
}
}
Both ways, we do the same thing and achieve the same goals.
(x --> 0) means (x-- > 0).
You can use (x -->)
Output: 9 8 7 6 5 4 3 2 1 0
You can use (-- x > 0) It's mean (--x > 0)
Output: 9 8 7 6 5 4 3 2 1
You can use
(--\
\
x > 0)
Output: 9 8 7 6 5 4 3 2 1
You can use
(\
\
x --> 0)
Output: 9 8 7 6 5 4 3 2 1 0
You can use
(\
\
x --> 0
\
\
)
Output: 9 8 7 6 5 4 3 2 1 0
You can use also
(
x
-->
0
)
Output: 9 8 7 6 5 4 3 2 1 0
Likewise, you can try lot of methods to execute this command successfully.
This --> is not an operator at all. We have an operator like ->, but not like -->. It is just a wrong interpretation of while(x-- >0) which simply means x has the post decrement operator and this loop will run till it is greater than zero.
Another simple way of writing this code would be while(x--). The while loop will stop whenever it gets a false condition and here there is only one case, i.e., 0. So it will stop when the x value is decremented to zero.
Here -- is the unary post decrement operator.
while (x-- > 0) // x goes to 0
{
printf("%d ", x);
}
In the beginning, the condition will evaluate as
(x > 0) // 10 > 0
Now because the condition is true, it will go into the loop with a decremented value
x-- // x = 9
That's why the first printed value is 9
And so on. In the last loop x=1, so the condition is true. As per the unary operator, the value changed to x = 0 at the time of print.
Now, x = 0, which evaluates the condition (x > 0 ) as false and the while loop exits.
--> is not an operator, it is the juxtaposition of -- (post-decrement) and > (greater than comparison).
The loop will look more familiar as:
#include <stdio.h>
int main() {
int x = 10;
while (x-- > 0) { // x goes to 0
printf("%d ", x);
}
}
This loop is a classic idiom to enumerate values between 10 (the excluded upper bound) and 0 the included lower bound, useful to iterate over the elements of an array from the last to the first.
The initial value 10 is the total number of iterations (for example the length of the array), and one plus the first value used inside the loop. The 0 is the last value of x inside the loop, hence the comment x goes to 0.
Note that the value of x after the loop completes is -1.
Note also that this loop will operate the same way if x has an unsigned type such as size_t, which is a strong advantage over the naive alternative for (i = length-1; i >= 0; i--).
For this reason, I am actually a fan of this surprising syntax: while (x --> 0). I find this idiom eye-catching and elegant, just like for (;;) vs: while (1) (which looks confusingly similar to while (l)). It also works in other languages whose syntax is inspired by C: C++, Objective-C, java, javascript, C# to name a few.
That's what you mean.
while((x--) > 0)
We heard in childhood,
Stop don't, Let Go (روکو مت، جانے دو)
Where a Comma makes confusion
Stop, don't let go. (روکو، مت جانے دو)
Same Happens in Programming now, a SPACE makes confusion. :D
The operator you use is called "decrement-and-then-test". It is defined in the C99 standard, which is the latest version of the C programming language standard. The C99 standard added a number of new operators, including the "decrement-and-then-test" operator, to the C language. Many C++ compilers have adopted these new operators as extensions to the C++ language.
Here is how the code without using the "decrement-and-then-test" operator:
#include <stdio.h>
int main()
{
int x = 10;
while (x > 0)
{
printf("%d ", x);
x--;
}
}
In this version of the code, the while loop uses the > operator to test whether x is greater than 0. The x-- statement is used to decrement x by 1 at the end of each iteration of the loop.