C++ : iterating the vector - c++

I'm very new to C++ and I'm trying to learn the vector in C++..
I wrote the small program as below. I like to foreach(var sal in salaries) like C# but it doesn't allow me to do that so I googled it and found that I have to use iterator.. Im able to compile and run this program but I dont get the expected output.. I'm getting "0 0 0 0 0 0 1 2 3 4 5 6 7 8 9" instead of "0 1 2 3 4 5 6 7 8 9"..
Could anyone please explain me why? Thanks.
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
void show(int i)
{
cout << i << " ";
}
int main(){
vector<int> salaries(5);
for(int i=0; i < 10; i++){
salaries.push_back(i);
}
for_each(salaries.begin(), salaries.end(), show);
}

You created a vector with 5 elements, then you push 10 more onto the end. That gives you a total of 15 elements, and the results you're seeing. Try changing your definition of the vector (in particular the constructor call), and you'll be set. How about:
vector<int> salaries;

This code creates a vector with a size of 5, and with each of those 5 elements initialized to their default value (0):
vector<int> salaries(5);
push_back inserts a new element, so here, you insert 10 new elements, ending up with a vector with 15 elements:
for(int i=0; i < 10; i++){
salaries.push_back(i);
}
You can create your vector like this instead:
vector<int> salaries;
and you'll get a vector with size 0.
Alternatively, you could initialize it with size 10, and then overwrite each element, instead of inserting new ones:
vector<int> salaries(10);
for(int i=0; i < 10; i++){
salaries[i] = i;
}
In some cases, it may be more efficient to write something like this:
vector<int> salaries; // create a vector with size 0
// allocate space for 10 entries, but while keeping a size of 0
salaries.reserve(10);
for(int i=0; i < 10; i++){
// because we reserved space earlier, these new insertions happen without
// having to copy the vector contents to a larger array.
salaries.push_back(i);
}

When you declare salaries(5), it's adding 5 entries into the vector with values of 0. Then your loop adds 0..9. Therefore you have 15 elements in your vector instead of just 10. Try declaring the vector without the 5.
vector<int> salaries;

vector<int> salaries(5); means, that you are creating the vector which contains 5 int objects from the start, and each int object is initialized with default constructor, and in the case of int contructor sets zero value. That's why you have 5 zero integers at the beginning of the vector container.

#Michael: Which book is that? I'd say
it's wrong. Using resize() is a good
practice if you know in advance how
big you need the vector to be, but
don't set the size at creation unless
you need the vector to contain
default-initialized values.
You can also reserve some capacity in the array in advance which is subtely different than re-size. Reserving simply reserves "at least" that much capacity for the vector (but does not change the size of the vector), while resize adds\removes elements to\from the vector to make it the requested size.

vector<int> salaries(5);
This creates a vector of 5 zeros for its elements. [0, 0, 0, 0, 0]
for(int i=0; i < 10; i++){
salaries.push_back(i);
}
This adds 10 more elements at the end ranging from 0 to 9 [0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Finally, I don't recommend using foreach so much. Functional programming has the downside of decentralizing code. It is extremely useful in some cases, but for these cases, and especially considering how you're starting out, I'd recommend:
for (vector<int>::const_iterator it = salaries.begin(), end = salaries.end(); it != end; ++it){
salaries.push_back(i);
}
Using this technique, you'll be able to iterate through any collection in the standard library without having to write separate functions or function objects for the loop body.
With C++0x you'll get a lot of goodies to make this easier:
for (int salary: salaries)
cout << salary << endl;
There's also BOOST_FOR_EACH already which is almost as easy if you can use boost.

Related

How to compare all elements of vector one to vector two and if a max element exists then comparing all the elements of vector two to vector three?

I want to compare all element of vector x to all elements of vector y and if I find a element greater in vector y than being compared to, I have to take that particular element of vector y and compare to all elements of vector z and if it is true return true else if i don't find a greater element in first iteration i,e when elements of vector x are compared to vector y i have to break the loop and return false.
I tried to iterate through all the elements of stackarmies but I don't know how to take the first element of vector one and compare with all the elements of vector, since all the vectors are merged into the last vector.
vector<int> stack;
int noofstack, noofoperations, stackno, OperationType;
// Taking the input number of stacks
cin >> noofstack;
vector<vector<int>> stackarmies;
for (int i = 0; i < noofstack; i++)
{
int stacksize;
//Since vectors are dynamic and we don't need to declare the size but as per the problem statement I've added it/
cin >> stacksize;
for (int k = 0; k < stacksize; k++)
{
//Taking the input of all the vectors one by one and then adding all the vectors into one vector
int armyheight;
cin>>armyheight;
stack.push_back(armyheight);
}
stackarmies.push_back(stack);
Test cases
Input 1
2
3 3 5 4
3 1 1 2
Resulting stackarmies: { {3, 5, 4}, {3, 5, 4, 1, 1, 2} }
Desired output: False
We will take first element of vector 1 : 3 and compare with all
elements of vector 2 , in vector 2 no element is greater than 3.
Input 2
2
3 1 0 4
3 2 1 3
Resulting stackarmies: { {1, 0, 4}, {1, 0, 4, 2, 1, 3} }
Desired output: True
We will take first element of vector 1 : 1 and compare with all
elements of vector 2, in vector 2, the first element is greater than 1,
so true
Input 3
2
3 1 9 0
2 0 11
Resulting stackarmies: { {1, 9, 0}, {1, 9, 0, 0, 11} }
Desired output: True
We will take first element of vector 1 : 1 and compare with all
elements of vector 2, in vector 2, the last element is greater than 1,
so true
Input 4
3
3 0 8 0
3 4 0 11
3 0 9 0
Resulting stackarmies: { {0, 8, 0}, {0, 8, 0, 4, 0, 11} , {0, 8, 0, 4, 0, 11, 0, 9, 0} }
Desired output: True
We will take the second element of vector 1: 8 and compare with
all elements of vector 2 , 11 is greater than 8 so we will compare 11 of
vector 2 with vector , since there are no values greater than 11, so it's
false
I don't know how to take the first element of vector one and compare with all the elements of vector, since all the vectors are merged into the last vector.
You're getting ahead of yourself. Why do you want all the vectors merged into the last vector? Answer: you don't; that's just what happened. Why did all the vectors merge into the last vector? Answer: because you have a bug in your code that reads the data. Fix that bug instead of spending ten times as much effort trying to handle the malformed data.
That whole spiel about what you intend to do next is nothing more than a distraction that wastes the time of the people from whom you are asking help. Ask for help with the real problem (the loading bug) instead of driving people away with a confusing question that assumes bad data is good.
There are several ways to fix the bug. I think the most helpful approach is one that would have avoided the bug in the first place. You try to do too much in a single function. Divide and conquer; when you have a non-trivial sub-step, create a function to handle it. Good programming practices lead to fewer bugs.
Specifically, reading the heights of the fighters in a stack is non-trivial. Delegate that to a helper and reduce the body of your outer for loop to a single line.
for (int i = 0; i < noofstack; i++)
{
//* This is non-trivial, so use a helper function.
stackarmies.push_back(read_fighter_heights());
}
This helper function is responsible for reading a line of data, generating a stack (a vector<int>) from it, and returning that stack. That covers most of the body of your loop, leaving only the simple task of pushing the returned stack onto your vector of stacks.
Creating this helper function from your existing code is fairly simple. Mostly, just move the body of the loop into an appropriate function definition. In addition, you should notice that stack is needed (only) in this function, so also move that variable's declaration into the new function's definition.
vector<int> read_fighter_heights()
{
vector<int> stack;
int stacksize;
//Since vectors are dynamic and we don't need to declare the size but as per the problem statement I've added it/
cin >> stacksize;
for (int k = 0; k < stacksize; k++)
{
//Taking the input of all the vectors one by one and then adding all the vectors into one vector
int armyheight;
cin>>armyheight; //* Reading a single integer is trivial, so no need for another function here.
stack.push_back(armyheight);
}
return stack;
}
Presto! Problem solved. All you had to do was be more organized.
Addendum: The reason this solves the problem is that extra step of moving the declaration of stack. In the original code, this variable was declared outside the outer loop, and it was never cleared. The result was that it accumulated values from each line that was read. In this version, the variable is re-initialized before reading each line, so values do not accumulate. You could get the same result by moving the line in the original code, without splitting off a new function. However, splitting off a new function is a good habit to get into, as it almost forces you to declare stack at the right level, avoiding the problem in the first place.
bool CompareVectors(vector<vector<int>> st)
{
bool result = true;
for (int k = 0; k < st.size(); k++)
{
if (k != st.size() - 1)
{
if (result)
{
for (auto i = st[k].begin(); i != st[k].end(); ++i)
{
for (auto j = st[k+1].begin(); j != st[k+1].end(); ++j)
{
if (*i < *j)
{
result = true;
break;
}
else
{
result = false;
}
}
if (result)
{
break;
}
}
}
}
}
return result;
}

Why does using push_back on a vector declared with size result in a vector of zeros?

I made a vector of constant size to store negative values, and then printing the values all I got was zeroes. I just want to know why it is not storing negative values.
#include <iostream>
#include <vector>
int main() {
std::vector<int> v(5);
v.push_back(-1);
v.push_back(-2);
v.push_back(-3);
v.push_back(-4);
v.push_back(-5);
for (int i=0; i<5; i++)
std::cout << v[i] << " "; // All I got was zeroes
}
That's because push_back puts new elements onto the end of the vector.
You can see the effect by running i to 9: the negative numbers will occupy v[5] to v[9].
Writing
std::vector<int> v{-1, -2, -3, -4, -5};
instead is a particularly elegant fix.
The constructor that you invoke fills the first 5 elements with zeros, see here (#3 in the list of overloads):
Constructs the container with count default-inserted instances of T
(where the "default-inserted instance" of an int is 0). What you might have wanted is
std::vector<int> v;
v.reserve(5); /* Prevent unnecessary allocations as you know the desired size. */
v.push_back(-1);
/* ... */
An alternative using the original constructor call is
#include <numeric>
std::vector<int> v(5);
std::iota(v.rbegin(), v.rend(), -v.size());
though this does more work than necessary as every element is first default constructed and then assigned to a new value again.
This is a case where the DRY principle would help you understand your mistake.
vector<int> v(5);
...
for(int i=0;i<5;i++)
Here you are creating an array, for which you think you reserve space for 5 elements. Then you insert those 5 elements. After that you wanted to print contents of the whole array, but instead of just writing v.size(), you repeated the 5, so that your code now reads like "Print first five elements of v", instead of "Print all elements of v".
If you instead wrote what you mean, you'd see that the array actually has 10 elements, not 5.
BTW, since C++11 you can loop over all elements in a more straightforward way:
for(int x : v)
or, if the elements were some more copy-expensive type, you could use references to the elements, even auto-type references:
for(auto& x : v)
This new for-loop syntax is called the range-based for loop.
You can consider the vector a flexible version of the primitive array in C/C++. When you initialize a vector with a size n, the constructed vector has size of n (or maybe larger in the memory, but you don't know since it's implicitly handled by compiler). Note that here n represents the number of entries, but not the actual memory usage (i.e. bytes). If you do not initialize it with a size parameter, the vector is empty with size 0, but in the memory it would have some implicit default memory size.
Let's say your current vector has size 5. And you want to push_back() in another element, then the vector internally will reallocate the entire array into a new memory location which could hold all its old entries plus the new one. So you don't need to reallocate the memory manually by yourself, like what you have to do in C.
Here, in your example, to fill in those 5 negative integers in your vector, there are a couple of ways.
1) You can initialize a vector without specifying the size. And then push in each element you want.
vector<int> v;
for (int i = -1; i >= -5; --i) {
v.push_back(i);
}
2) You can initialize the vector in your way with that size parameter. And then assign them with new values.
vector<int> v(5);
for (int i = 0; i < v.size(); ++i) {
v[i] = -i;
}
3) You can also initialize the vector with those entries when it is constructed.
vector<int> v{-1, -2, -3, -4, -5};
or vector<int> v = {-1, -2, -3, -4, -5};
When you declared the vector with
std::vector<int> v(5);
You made v store five 4-byte spaces in memory (assuming an int = 4 bytes on your system), and by default all of these 4-byte spaces store the bits representing 0's. Then, you pushed 5 more ints (-1, -2, -3, -4, -5) onto the end of the vector with:
v.push_back(-1);
v.push_back(-2);
v.push_back(-3);
v.push_back(-4);
v.push_back(-5);
At this point the vector has 10 elements, the first five being the unknown ints that happen to store 0's on the instance you ran the program. Since your for loop prints the first five elements in the vector, this is why it printed all 0's.
When you declared this line vector<int>v(5) it created a vector of size 5 with default value of all elements 0, at this stage your vector looks like this -
{0, 0, 0, 0, 0}
Now when you called v.push_back(-1) what it did is it pushed -1 to the back of vector increasing its size, now your vector looks like this -
{0, 0, 0, 0, 0, -1}
After every push back is performed your final vector will be - {0, 0, 0, 0, 0, -1, -2, -3, -4, -5}
The size of your vector is now increased to 10 from 5 and when you looped from index 0 to 4 it only printed 0. I hope I explained it well and fix for this is already provided in previous answers.

Not getting the input values when printing vector of pairs

I want to add a pair to a vector of pairs.
When I print the vector elements, I don't get the integers I input.
Please help.
#include<iostream>
#include<vector>
#include<utility>
using namespace std;
int main()
{
vector<vector<unsigned long int> >matrix;
vector<pair<int,int> >pmat;
int L;
cin>>L;
int n1, n2;
pmat.resize(L);
for(int k = 0; k<L; k++)
{
cin>>n1>>n2;
pair<int,int> p = make_pair(n1,n2);
cout<<p.first<<p.second<<endl;
pmat.push_back(p);
}
for(int k = 0; k<L; k++)
{
cout<<pmat[k].first<<','<<pmat[k].second<<' ';
}
cout<<endl;
return 0;
}
Method 1:
Delete this line:
pmat.resize(L);
You don't need to resize it in the first place as you do push_back() when adding afterwards.
Method 2:
Change the following line
pmat.push_back(p);
to
pmat[k] = p;
You can do resize() in the first place, but after this, you should not use push_back() when adding, just use pmat[k] = p.
PS: you should not mix these two ways up. Always use one of them consistently.
Since you're using pmat.resize(L) and L times pmat.push_back(...), you're ending up having stored 2 * L entries in your vector. However you're printing just the first half, index 0 to L - 1. The values you want are stored from index L to 2 * L - 1.
Just change pmat.resize(L) to pmat.reserve(L).
Alternatively, you can use the resize(L), but to end up with L entries, you need to store each input pair to pmat[k], hence you write pmat[k] = p;.
As a rule of thumb, I recommend using the reserve + push_back approach if you know how many elements you're going to add. The reason is, that resize initializes the elements, while reserving just asserts that there will be enough space and no reallocation will be necessary with any following push_back.
You don't want to add more pairs after you allocated them. You can now directly access them.
Just use pmat[k] = p; instead of pmat.push_back(p);
If you print the size of the vector after reading the values, you will notice a small problem with your program:
./test
2
1 2
12
3 4
34
Size of the vector: 4
0,0 0,0
Huh? Even though I only entered 2 pairs, the size of the vector is 4. How did this happen?
If you look at the documentation for resize, it says
Resizes the container to contain count elements.
So even before you read any values, your vector will already contain 2 elements! Those will be default-constructed and therefore be 0. When you then push_pack the elements you read in, those will land at the indices 2 and 3 in the vector, so the end vector has twice as much elements as you wanted (4 in this case). You only print out the first half, which are the zero values.
The solution is to use reserve instead of resize, which doesn't create the elements but only reserves space for them, or just delete the call to resize. Using reserve is more efficient though, because then the vector will only need to allocate memory once.
pmat.resize(L);
if vector in empty its going to initialize a vector pmat with size L then assign default values to vector so now pmat size is L with default values
for(int k = 0; k<L; k++)
{
cin>>n1>>n2;
pair<int,int> p = make_pair(n1,n2);
cout<<p.first<<p.second<<endl;
pmat.push_back(p);
}
then u r pushing values to pmat L times so the final size is 2*L
for(int k = 0; k<L; k++)
{
cout<<pmat[k].first<<','<<pmat[k].second<<' ';
}
here u r going to read from 0 to L-1 , it contains default values you can see your values from L-1 to 2L-1.
so finally what i want say is use reserve instead of resize
or
pmat.resize(L); comment this line

Finding smallest values of given vectors

How can I find the smallest value of each column in the given set of vectors efficiently ?
For example, consider the following program:
#include <iostream>
#include <vector>
#include <iterator>
#include <cstdlib>
using namespace std;
typedef vector<double> v_t;
int main(){
v_t v1,v2,v3;
for (int i = 1; i<10; i++){
v1.push_back(rand()%10);
v2.push_back(rand()%10);
v3.push_back(rand()%10);
}
copy(v1.begin(), v1.end(), ostream_iterator<double>(cout, " "));
cout << endl;
copy(v2.begin(), v2.end(), ostream_iterator<double>(cout, " "));
cout << endl;
copy(v3.begin(), v3.end(), ostream_iterator<double>(cout, " "));
cout << endl;
}
Let the output be
3 5 6 1 0 6 2 8 2
6 3 2 2 9 0 6 7 0
7 5 9 7 3 6 1 9 2
In this program I want to find the smallest value of every column (of the 3 given vectors) and put it into a vector. In this program I want to define a vector v_t vfinal that will have the values :
3 3 2 1 0 0 1 7 0
Is there an efficient way to do this ? I mention efficient because my program may have to find the smallest values among very large number of vectors. Thank you.
Update:
I'm trying to use something like this which I used in one of my previous programs
int count = std::inner_product(A, A+5, B, 0, std::plus<int>(), std::less<int>());
This counts the number of minimum elements between two arrays A and B. Wouldn't it be efficient enough if I could loop through and use similar kind of function to find the minimal values ? I'm not claiming it can be done or not. It's just an idea that may be improved upon but I don't know how.
You can use std::transform for this. The loops are still there, they're just hidden inside the algorithm. Each additional vector to process is a call to std::transform.
This does your example problem in two linear passes.
typedef std::vector<double> v_t;
int main()
{
v_t v1,v2,v3,vfinal(9); // note: vfinal sized to accept results
for (int i = 1; i < 10; ++i) {
v1.push_back(rand() % 10);
v2.push_back(rand() % 10);
v3.push_back(rand() % 10);
}
std::transform(v1.begin(), v1.end(), v2.begin(), vfinal.begin(), std::min<double>);
std::transform(v3.begin(), v3.end(), vfinal.begin(), vfinal.begin(), std::min<double>);
}
Note: this works in MSVC++ 2010. I had to provide a min functor for gcc 4.3.
I think that the lower bound of your problem is O(n*m), where n is the number of vectors and m the elements of each vector.
The trivial algorithm (comparing the elements at the same index of the different vectors) is as efficient as it can be, I think.
The easiest way to implement it would be to put all your vectors in some data structure (a simple C-like array, or maybe a vector of vectors).
The bst way to do this would be to use a vector of vectors, and just simple looping.
void find_mins(const std::vector<std::vector<int> >& inputs, std::vector<int>& outputs)
{
// Assuming that each vector is the same size, resize the output vector to
// change the size of the output vector to hold enough.
output.resize(inputs[0].size());
for (std::size_t i = 0; i < inputs.size(); ++i)
{
int min = inputs[i][0];
for (std::size_t j = 1; j < inputs[i].size(); ++j)
if (inputs[i][j] < min) min = inputs[i][j];
outputs[i] = min;
}
}
To find the smallest number in a vector, you simply have to examine each element in turn; there's no quicker way, at least from an algorithmic point-of-view.
In terms of practical performance, cache issues may affect you here. As has been mentioned in a comment, it will probably be more cache-efficient if you could store your vectors column-wise rather than row-wise. Alternatively, you may want to do all min searches in parallel, so as to minimise cache misses. i.e. rather than this:
foreach (col)
{
foreach (row)
{
x_min[col] = std::min(x_min[col], x[col][row]);
}
}
you should probably do this:
foreach (row)
{
foreach (col)
{
x_min[col] = std::min(x_min[col], x[col][row]);
}
}
Note that STL already provides a nice function to do this: min_element().

Swapping blocks of elements in an array

I am working on C++.. am in a need to swap two blocks of elements in an array..
Say, {1,2,3,4,5,6} is my input array.. block {4,5} should be moved to beginning and the output array should be like {4,5,1,2,3,6}.. all i have is the start index and end index of the block {4,5}.. for doing this i am using a temp array, copying the blocks individually to temp array and moving it back to the original array, which is tedious
but i am sure there will be better methods to do this using memcpy or memmove.. any ideas?
There is a standard algorithm designed specifically for this task called std::rotate():
#include <algorithm>
#include <cstdio>
int main()
{
int inputArray[] = {1, 2, 3, 4, 5, 6};
::printf("Before: ");
for(int i = 0; i < 6; ++i)
{
::printf("%d ", inputArray[i]);
}
::printf("\n");
int startIndex = 3; // refers to the number 4 in inputArray
int endIndex = 5; // refers one-past the number 5 in inputArray
std::rotate(inputArray, inputArray+startIndex, inputArray+endIndex);
::printf("After: ");
for(int i = 0; i < 6; ++i)
{
::printf("%d ", inputArray[i]);
}
::printf("\n");
}
Expected output:
Before: 1 2 3 4 5 6
After: 4 5 1 2 3 6
std::rotate() performs the rotation in-place via std::swap(), so there's no temporary array involved.
Bentley's "Programming Pearls" describes three algorithms for solving this problem. You can find slides for this specific problem here
http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf
For example, the simplest algorithms would be the Reversal one. Just reverse the blocks that you need to swap, and then reverse the entire array. Done.
P.S. In your example "the entire array" would stand for the 1,2,3,4,5 subsequence (6 is not included), since these are the blocks that you need to swap.
Reverse the blocks:
3, 2, 1, 5, 4
Reverse the whole thing
4, 5, 1, 2, 3