Pesky ol' Vectors

Program has to put evens into one vector, odds in the other, and output them. I currently have this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Vector Worksheet 2.cpp : Defines the entry point for the console application.
//

#include <iostream>
#include <vector>
using namespace std;
int number = 0;
void print(const vector<int>&);//utility function outputs a vector of ints
void print_backwords(const vector<int> &);
int main()
{
	vector<int> v;

	cout << "Input some numbers and then end the input\n";
	cout << "Input number: ";
	cin >> number;
	while (number >= 0)
	{
		v.push_back(number);
		cout << "Input number: ";
		cin >> number;
	}//while(more)

	print(v);
	print_backwords(v);
	system("pause");
	return 0;
}
void print_backwords(const vector<int> &a)
{
	for (int i = a.size() - 1; i >= 0; --i)
		cout << a[i] << " ";
	cout << endl;
	cout << "----------------" << endl;
}// print_backwords

void print(const vector<int> &x)
{
	for (int j = x.size() -1; j >= 0; ++j)
		cout << x[j] << " ";
	cout << endl;
	cout << "----------------" << endl;
}

Can't figure out how to make it put odd and even numbers into separate vectors and output them.
Last edited on
Hello Databen,

Vectors are not pesky they are your best friend. Now using namespace std; that is pesky.

In the print function you define two vectors. That part is good. Then the for loop is wrong the whole while loop is wrong.

The for loop looks like an endless loop. I think what you want is:
for ((int j = 0; j < x.size(); j++).

For the while loop I see where "number" came from, but it is the wrong variable to use. Actually I would do away with the while loop because you can do everything in the for loop.

The if/else if what is even = even; even mean? "even" and "odd" should be a push_back like you did in main and what would be inside the () should be "x[j]".

Line 54 just because it is indented under the while loop does not make it part of the while loop or the for loop. Lines 54 on are separate from either loop.

Hope that helps,

Andy
unless it is printing words and you are feeling creative, you want 'backwards'.

if and when you know, its useful to always give a vector a default size:

vector <int> v(100); //now it can hold up to 100 without any fuss. This will be very important to you later when you start dealing with larger amounts of data, which may not happen at all until after school.

number is a global variable. Global variables are a very bad habit, try to stop using them as soon as possible.

extra work is slowness in your programs, and extra code is more to wade through reading it.

math tells us that value%2 is either zero, or it isnt. So consider
if(value%2 ==0)
do someting
else //no more if, don't do the division again
do the other thing

instead of doing the math twice.

These are not 'wrong' so much as 'could be better'.


Last edited on
jonnin wrote:
So consider
if(value%2 ==0)

More fun is just to use bitwise and. if (value&1) // odd

Databend, can you explain the problem? (What is happening, what do you want to happen, etc.?)
Last edited on
I think you just added an extra loop and then ran into trouble. Try to make single passes if you can, or make multiple passes if possible instead of nesting. Nesting loops is O(n*n) time, exponential, while multiple passes is just O(2n) or O(3n) etc, still linear. Can run this at https://repl.it/repls/SpitefulThinDemands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <vector>

using namespace std;

void print_normal(const vector<int>& v)
{
    cout << "normal: ";
    for (auto& n : v)
        cout << n << " ";
    cout << endl;
}

void print_reversed(const vector<int>& v)
{
    cout << "reversed: ";
    for (int i=v.size()-1; i>=0; --i)
        cout << v[i] << " ";
    cout << endl;
}

void print_evens_odds(const vector<int>& v)
{
    vector<int> odds;
    cout << "evens: ";
    for (auto& n : v)
    {
        if (n&1)
            odds.push_back(n);
        else
            cout << n << " ";
    }
    cout << "\nodds: ";
    for (auto& n : odds)
        cout << n << " ";
    cout << endl;
}

int main() 
{
    int nums = 5;
    vector<int> vec;
    vec.reserve(nums);
    cout << "Input "<<nums<<" numbers separated by spaces\n";
    
    int n;
    for (int x=1; x<=nums; ++x)
    {   
        cin >> n;
        vec.push_back(n);
    }
    
    print_normal(vec);
    print_reversed(vec);
    print_evens_odds(vec);
    
    return 0;
}
Last edited on
The problem is making the program put all odds into one vector, evens in the other, and printing the contents of both vectors once I run the program, put in all the numbers, and end the loop. I can't figure out how to do this and along with that I don't really understand half of the code in the actual program because it was a template our teacher gave us, that we had to build off of. So originally I got

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 // Vector Worksheet 2.cpp : Defines the entry point for the console application.
//

#include <iostream>
#include <vector>
using namespace std;
int number = 0;
void print(const vector<int>&);//utility function outputs a vector of ints
void print_backwords(const vector<int> &);
int main()
{
	vector<int> v;

	cout << "Input some numbers and then end the input\n";
	cout << "Input number: ";
	cin >> number;
	while (number >= 0)
	{
		v.push_back(number);
		cout << "Input number: ";
		cin >> number;
	}//while(more)

	print(v);
	print_backwords(v);
	system("pause");
	return 0;
}
void print_backwords(const vector<int> &a)
{
	for (int i = a.size() - 1; i >= 0; --i)
		cout << a[i] << " ";
	cout << endl;
	cout << "----------------" << endl;
}// print_backwords 


and then I had to add this code on my own, which afterwords worked in allowing me to input numbers.

1
2
3
4
5
6
7
8
void print_backwords(const vector<int> &x)
void print(const vector<int> &x)
{
	for (int j = x.size() -1; j >= 0; ++j)
		cout << x[j] << " ";
	cout << endl;
	cout << "----------------" << endl;
}

To make it actually allow you to input numbers with a loop, which works. Now I need to add code that will sort out odds and evens, putting them into an odd and even vector, and then printing them out
There are no comments that tell me what does what, so I've had to do a lot of googling and I'm currently on spring break so can't ask the teacher for help..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;

bool isOdd ( int n ) { return   n % 2 ; }
bool isEven( int n ) { return !(n % 2); }

int main()
{
   vector<int> V = { 1, 2, 3, 4, 5, 6, 7 };
   ostream_iterator<int> out( cout, " " );
   cout << "Forwards:  ";   copy   ( V.begin() , V.end() , out )        ;   cout << '\n';
   cout << "Backwards: ";   copy   ( V.rbegin(), V.rend(), out )        ;   cout << '\n';
   cout << "Odd:       ";   copy_if( V.begin(),  V.end() , out, isOdd  );   cout << '\n';
   cout << "Even:      ";   copy_if( V.begin(),  V.end() , out, isEven );   cout << '\n';
}


Forwards:  1 2 3 4 5 6 7 
Backwards: 7 6 5 4 3 2 1 
Odd:       1 3 5 7 
Even:      2 4 6



It's not clear that you have to create new vectors before printing them out ... or just print the odd and even numbers from the existing vector.

n % 2 will be 1 if n is odd, 0 if n is even.
Use this to test for odd or evenness.


If you want to create new vectors for odd and even then create empty vectors:
vector<int> Odd, Even;
Then loop through the elements of your original vector and use
Odd.push_back( n );
if n is odd and
Even.push_back( n )
otherwise.
Then just print out the elements of Odd in a loop, followed (after a new line) by the elements of Even.


If you don't need to create new vectors then just loop through your original vector twice, the first time printing out odd numbers, the second time printing out even numbers.
Hello Databen,

You changed your original code. Do not do that. It makes it hard to follow. If you change your code put it in a new message.

The "print_backwords" function of your original code worked fine as long as you wanted to print all numbers from the original vector in main.

The original "print" function is a good start just needed fixed and I added some code to print out each vector. Actually I am thinking of a function to separate the even and odd numbers then the "print" function to just print them out.

See my previous message. If something is not clear point it out and we can cover that.

your original program was close with the proper changes it works. I have it working.

Let me know what you do not understand and we can cover it.

Hope that helps,

Andy
Hello Databen,

lastchance has a good example, but this may be beyond what you know.

This may be more along with what you know.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void SplitNumbers(const std::vector<int> &v, std::vector<int> &even, std::vector<int> &odd)
{
	for (std::size_t j = 0; j < v.size(); ++j)
	{
		if ((v[j] % 2) == 0)
		{
			even.emplace_back(v[j]);
		}
		else// if ((number % 2) != 0)
		{
			odd.emplace_back(v[j]);
		}
	}
}


The vectors "even" and "odd" are defined in main and passed to the functions that need them.

Hope this helps,

Andy
Okay, thanks to you all I have got it working perfectly, thanks!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

// Vector Worksheet 2.cpp : Defines the entry point for the console application.
//

#include <iostream>
#include <vector>
using namespace std;
int number = 0;
void print(const vector<int>&);
int main();
//utility function outputs a vector of ints
void print_backwords(const vector<int> & v);
void print_evens_odds(const vector<int>& v);
void print_normal(const vector<int>& v);
int main()
{
	vector<int> v;

	cout << "Input some numbers and then end the input using -1\n";
	cout << "Input number: ";
	cin >> number;
	while (number != -1)
	{
		v.push_back(number);
		cout << "Input number: ";
		cin >> number;
	}//while(more)

	print_normal(v);
	print_backwords(v);
	print_evens_odds(v);
	system("pause");
	return 0;
}
void print_backwords(const vector<int>& v)
{
	cout << "reversed: ";
	for (int i = v.size() - 1; i >= 0; --i)
		cout << v[i] << " ";
	cout << endl;
}// print_backwords

void print_normal(const vector<int>& v)
{
	cout << "normal: ";
	for (auto& n : v)
		cout << n << " ";
	cout << endl;
}

void print_evens_odds(const vector<int>& v)
{
	vector<int> odds;
	cout << "evens: ";
	for (auto& n : v)
	{
		if (n & 1)
			odds.push_back(n);
		else
			cout << n << " ";
	}
	cout << "\nodds: ";
	for (auto& n : odds)
		cout << n << " ";
	cout << endl;
}

Last edited on
Hello Databen,

Very good.

if you are finished green check the thread so everyone will know.

Andy
This is just my selfish opinion, but when I see people doing "n & 1", I tend to think they're trying to "outsmart" the compiler and are usually arrogant programmers :^) But perhaps they just see n & 1 as simply more intuitive than n % 2 == 1. I personally would much rather think of it terms of modular arithmetic, but maybe that's just me.
Not that I'm implying that Databend is being arrogant or anything bad!

A big reason for this is that I see %2 as being a lot more extendable than &1. The &1 only works because of the particular nature of binary numbers in computers; an internal detail that you don't have to know about (although it's hard to avoid this at times). %2, on the other hand, can easily be extended into %3, %100, etc. There's no nice way to say "number divisible by 3" using bit twiddling.
Last edited on
Ganado wrote:
This is just my selfish opinion, but when I see people doing "n & 1", I tend to think they're trying to "outsmart" the compiler and are usually arrogant programmers :^) But perhaps they just see n & 1 as simply more intuitive than n % 2 == 1. I personally would much rather think of it terms of modular arithmetic, but maybe that's just me.
Not that I'm implying that Databend is being arrogant or anything bad!

I introduced n&1 to this thread ;D Idk... I personally do find it more readable.
Perhaps it all started with some golf-style code I once saw, and it has since served as a friendly reminder that binary operations can be cool, too! Also, while some people might like to ask the question "Is n even?", the code bit if (n&1) very concisely checks if n is odd. For use-cases where a check for odd is needed, if (n%2 != 0) might make the reader stop for a bit because of the negation.

Edit: also from googling, apparently compilers tend to turn n%x operations into n&(x-1)
Last edited on
Yeah, I suppose that it can be more easily readable for some people, although I wouldn't take "best practices" from code golfing...
You could also say n%2 == 1 to avoid the negation.

Edit: also from googling, apparently compilers tend to turn n%x operations into n&(x-1)

I don't see how that works.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

bool boolean(int value)
{
    return !!value;   
}

int main()
{
    int mod = 3;
    for (int i = 0; i < 16; i++)
    {
        std::cout << "i = " << i << ":\t" << 
            boolean(i % (mod)) << " " <<
            boolean(i & (mod-1)) << "\n";
    }
}


But anyway, I'm just nitpicking over something that doesn't really matter with the %2 thing... it's just a personal opinion, I probably shouldn't butt in. :p
Last edited on
not sure what % looks like on the chip, but & is a very simple circuit. Most CPU circuits are made of nand gates... so & is a natural at the chip level. But the compiler may convert some %s for you anyway. /shrug. Worry about if you have to do billions of them.

you can also shift off to the last bit and treat that as a boolean for even/odd. There are probably over a dozen ways to check even/odd (some of them terrible, of course, like pulling off a digit from a to-string and checking that against the even's list). You can also compare shifting once and division by 2. If those are equal, its even (shifting 1 bit left or right is multiply or divide by 2, and usually cheaper than either on the chip).



@Ganado, probably needs to be a power of 2.
1
2
3
1071 % 32 == 1071 & 31  // true
1099 % 16 == 1099 & 15  // true
3801571803 % 8 == 3801571803 & 7 // true 
Last edited on
Well then it's not an extendable solution, and I go back to saying % is superior for purposes of readable divisibility checks. :p
But for the original discussion: I now understand why people might prefer n & 1 :)

@jonnin
For powers of 2 they definitely compile to the same thing, the compiler is smart enough :)
Last edited on
Topic archived. No new replies allowed.