forloop, iterators and vectors doesn't cooperate with me - c++

Why does this work fine for me:
for(int i = 0; i < vec.size(); i++)
{
os << vec[i] << " ";
}
while this doesn't:
for(vector<int>::iterator it = vec.begin(); it < vec.end(); it++)
{
os << vec[*it] << " ";
}

You should be printing *it instead of using it as the index and you should probably change the condition to it != vec.end().

You're using the iterator wrong, it should be:
for(vector<int>::iterator it = vec.begin(); it < vec.end(); it++)
{
os << *it << " ";
}
Your code just attempts to print the element at index *it, which might not even be valid.

Related

iterator a set in array c++

#include <iostream>
#include <unordered_set>
using namespace std;
void arraySet(unordered_set<int> n[]){
for(auto it1 = n->begin(); it1!= n->end(); it1++){
cout << "n[" <<*it1<<"]: ";
// for(auto it = it1->begin(); it!= it1->end(); it++){
// cout << *it <<" ";
// }
cout << endl;
}
}
int main()
{
unordered_set<int> n[3];
n[0].insert(734);
n[0].insert(23);
n[0].insert(634);
n[1].insert(2);
n[1].insert(1);
n[2].insert(1);
arraySet(n);
return 0;
}
Can anyone help me explain how to iterator through this set inside array. I believe an easy way is to convert it to set inside vector.
Size of the array needs to be passed as well to the function for you to be able to iterate through all the sets of the array. With just passing the pointer, size cannot be determined and dereferencing n->begin will iterate through only the first set.
void arraySet(unordered_set<int> n[], int size) {
for (auto i = 0; i < size; i++) {
for (auto it1 = n[i].begin(); it1 != n[i].end(); it1++) {
cout << "n[" << *it1 << "]: ";
// for(auto it = it1->begin(); it!= it1->end(); it++){
// cout << *it <<" ";
// }
cout << endl;
}
}
}
int main()
{
unordered_set<int> n[3];
n[0].insert(734);
n[0].insert(23);
n[0].insert(634);
n[1].insert(2);
n[1].insert(1);
n[2].insert(1);
arraySet(n,3);
return 0;
}
Or you could use std::vector to contain the sets and pass it instead.
std::vector<unordered_set<int>> n(3); // Sets the size to 3 elements
The function definition would be changed to
void arraySet(std::vector<unordered_set<int>>& n) {
for (size_t i = 0; i < n.size(); i++) {
for (auto it1 = n[i].begin(); it1 != n[i].end(); it1++) {
cout << "n[" << *it1 << "]: ";
// for(auto it = it1->begin(); it!= it1->end(); it++){
// cout << *it <<" ";
// }
cout << endl;
}
}
}

How to iterate first ten items from the container

I want to print only first 10 inserted items while leaving the rest behind. What code do i have to use (instead of using myset.end() ) to print only first 10 integers instead of printing every single integer.
int main ()
{
std::set<int> myset;
std::set<int>::iterator it;
// set some initial values:
for (int i=1; i<=20; ++i)
myset.insert(i*10);
std::cout << "myset contains:";
for (it=myset.begin(); it!=myset.end(); ++it)
std::cout << *it << ' ';
std::cout << "\n\n";
return 0;
}
You might use std::next as follow:
const auto begin = myset.begin();
const auto end = myset.size() < 10 ? myset.end() : std::next(begin, 10);
for (auto it = begin; it != end; ++it) {
std::cout << *it << ' ';
}
You can just keep a count variable and break the loop as soon as it reaches 10 or you reach myset.end().
int main ()
{
std::set<int> myset;
std::set<int>::iterator it;
// set some initial values:
for (int i=1; i<=20; ++i)
myset.insert(i*10);
int count = 0;
std::cout << "myset contains:";
for (it=myset.begin(); count < 10 && it!=myset.end(); ++it, ++count)
std::cout << *it << ' ';
std::cout << "\n\n";
return 0;
}
I would do it like this:
int nCount = 0;
for (it=myset.begin(); nCount<10 && it!=myset.end(); ++nCount, ++it)
{
std::cout << *it << ' ';
}
Hope this helps.

Delete an element from a list C++

I have a problem, I'm trying to delete an element in a string list but it doesn't work for the last position. I would also like to display the position of the iterator with an arithmetic operation.
list l = {"a","b","c", "d"};
for(std::list<string>::iterator it = l.begin(); it != l.end(); it++)
cout << " &l["<< it - l.begin() <<"]: " << &*it << " l["<< it - l.begin() <<"]: " << *it << endl;
cout << endl;
for(std::list<string>::iterator itt = l.begin(); itt != l.end(); itt++){
if(*itt == "d") itt = l.erase(itt);
cout << " &l["<< itt - l.begin() <<"]: " << &*itt << " l["<< itt - l.begin() <<"]: " << *itt << endl;
}
Thank you for your help.
It "doesn't work" because this line will cause itt to become the end() iterator when erasing the last element:
if(*itt == "d") itt = l.erase(itt);
Then the for loop does itt++ before the loop condition check, and incrementing the end() iterator is undefined behavior.
You need to modify your loop like this:
for (std::list<string>::iterator itt = l.begin(); itt != l.end(); /* */) {
if (*itt == "d") {
itt = l.erase(itt);
} else {
++itt;
}
// You cannot safely access *itt here because it might be l.end()
}
Two issues. First:
it - l.begin()
List iterators aren't random access, so they don't have operator-() defined for the obvious reason that that would be an expensive operation. If you want to do that, you have to do:
std::distance(l.begin(), it);
Second, the line:
itt = l.erase(itt);
for the last element will cause itt to become l.end(), so the subsequent itt++ is undefined behavior. What you will have to do instead is conditionally increment the iterator:
for (std::list<string>::iterator itt = l.begin(); itt != l.end(); /* nothing */) {
if (*itt == "d") {
itt = l.erase(itt);
}
else {
// cout stuff here
++itt;
}
}

Why does this vector iterator not become invalidated?

I've read a few posts concerning iterator invalidation, and it seems that inserts that require a vector reallocation would invalidate iterators. Also shouldn't erases in the middle of the vector cause an invalidation?
I don't have a clear understanding of this, not sure why using these iterators after resizes and erases from begin, middle, and end doesn't break them:
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, char** argv) {
vector<int> v;
v.reserve(10);
for (int i = 0; i < 10; i++)
v.push_back(i);
for (auto x = v.begin(); x != v.end(); x++) {
cout << *x << endl;
}
cout << endl << "RESIZE" << endl << endl;
for (int i = 10; i < 20; i++)
v.push_back(i);
for (auto x = v.begin(); x != v.end(); x++) {
cout << *x << endl;
}
cout << endl << "RESIZE 2" << endl << endl;
for (int i = 20; i < 200; i++)
v.push_back(i);
for (auto x = v.begin(); x != v.end(); x++) {
cout << *x << endl;
}
cout << endl << "REMOVES" << endl << endl;
v.erase(v.begin());
v.pop_back();
v.erase(v.begin() + 17);
for (auto x = v.begin(); x != v.end(); x++) {
cout << *x << endl;
}
return 0;
}
Note that calling begin() or end() will always provide a sane iterator
However something like:
std:vector<int> v;
....
std::vector<int>::iterator i=v.begin();
v.erase(i);
std::cout << *i << std::endl; // i iterator was invalidated by erasing it
// trying to access it or increment it is undefined behaviour.
std::cout << *v.begin() << std::endl; // begin() provides always a sane iterator.
In your code, always when iterators are reused, there was no intervening modification of the vector, so no invalidation.
Iterators may be invalidated on resizing and inserting. Erasing only invalidates iterators at or after the erased element.
At least, those are the paraphrased rules for std::vector.

How to print a vector array?

I have a vector array called nVectors.
vector<int>* nVectors[21];
for (int i = 1; i <= 20; i ++) {
nVectors[i] = generateVector(i);
}
I can print all the members of a single vector, but when it comes to the vector array, I still don't know how to print all the vectors in an array.
Maybe an iterator through all the member of a vector array and print using my predefined method pvector can solve this problem? But I don't know how to iterate in gdb.
std::array<std::vector<int>*, 21> nVectors;
for(std::array<std::vector<int>*>::iterator i = nVectors.begin();
i != nVectors.end();
++i)
{
for(std::vector<int>::iterator it = (*i)->begin();
it != (*i)->end();
++it)
{
std::cout << *it << " ";
}
}
std::cout << std::endl;
Or, in C++11:
std::vector<int>* nVectors[21];
for(auto &i : nVectors)
{
for(auto &it : i)
{
std::cout << *it << " ";
}
}
std::cout << std::endl;