C++ Vectors not performing as intuitively as I thought - c++

I've been trying to learn how to use vectors in c++, and they seem much more complicated in java. In order to add items to a vector, I've had to use an iterator. What I'd like to be able to do is just use add remove functions and loop over them as in java. Is this possible? I'm trying to achieve something like the line I marked with an error below : insert(index 3, number 13), but this throws an error. Thanks in advance.
vector<int> myvector(0,0);
vector<int>::iterator it;
it = myvector.begin();
int q = 0;
for(it=myvector.begin();q<16;q++){
it = myvector.insert (it, q);
}
myvector.insert(3,13); //ERROR

You got advice above how to populate the vector.
If you want to insert something at specific index, you can do the following
//similar to myvector.insert(3,13); //ERROR
myvector.insert( myvector.begin()+3, 13);
The code above will insert 13 before element #3 so that 13 becomes element #3 (numeration starts with 0, so "begin" corresponds to element #0).
To replace element #3 with 13, you simply use
myvector[3] = 13;

Here is the link where you can learn about the C++ STL(Standard Template Library), such as: vector, queue, stack, list etc.

Related

How to copy whole vector into queue in reversed order?

My vector stores the numbers of the vertices of a certain graph in ascending order. I want to add these numbers to a queue in order to run BFS later in code, but I dont know how do that in nice and fast way. I want the solution to be clear for everyone to read and what I came with is in my opinion obscure.
Disclaimer - I use static casts because i hate seeing warnings when i work with Qt. Here's what did:
Using casual for loop to iterate in reverse order through the vector starting with size-1 ending when i equals -1. Because I'm using -1 as rule I need to cast everything on int which makes code ugly.
vector<unsigned> v;
v.pushback(2);
v.pushback(3);
v.pushback(5);
queue<unsigned> q;
for(int i = static_cast<int>(v.size()-1); i>=0; i--)
q.push(v[static_cast<unsigned>(i)];
Can someone tell me how pros do it? Cant find anything like "copy in reverse order" function that can start from .end()-1 element and copy all elements including .begin() one?
std::vector provides the functions rbegin and rend which return reverse iterators that you can use to iterate from the back to the front. Using those you can use std::for_each to iterate the vector and then use a lambda as the functor to push each element into the queue. That would look like
std::vector<int> v = {1, 2, 3};
std::queue<int> q;
std::for_each(v.rbegin(), v.rend(), [&q](auto el){ q.push(el); });

copying part of a list to a vector in C++

Im getting back into c++ after a decade away from it.
Im trying to get the last 5 items of a list and sort them. Here is the code I have so far.
int myints[] = {32,55,34,22,33,55,22};
std::list<int> mylist(myints, myints+7);
std::vector<int> myvector2(mylist.end() - 5, mylist.end());
std::sort(myvector2.begin(), myvector2.end());
However I am getting the following error.
invalid operands to binary expression ('iterator' (aka '__list_iterator<int, void *>') and 'int')
What am I doing wrong? Is there a better way to do this.
Your code shows the age of your knowledge. Since C++ 11, you've been able to initialize containers more directly:
std::list<int> mylist{32,55,34,22,33,55,22};
For the question you're actually asking, I'd use prev:
std::vector<int> myvector2(std::prev(mylist.end(), 5), mylist.end());
You can also use std::advance, but it doesn't return the value it produces, so it's often somewhat clumsy to use:
auto pos = mylist.end();
std::advance(pos, -5);
std::vector<int> myvector2(pos, mylist.end());
As a final note, I'd advise that almost any use of std::list should be treated as "guilty until proven innocent". It's rarely useful--even in cases that are devised specifically to highlight its (supposed) advantages, std:vector frequently ends up faster.

C++ Vector.erase() causing segmentation fault

I have a C++ vector and it has some blank elements in it. I wanted to remove any empty string elements from the vector. I tried this code:
for (i = 0; i < myvector.size();i++) {
if (myvector[i] == "") {
myvector.erase(myvector.begin()+i);
}
}
When I run this code I get a segmentation fault. Is there something wrong with it? Or does this code work for any of you?
It appears that you want the usual remove-erase idiom:
#include <algorithm>
#include <functional>
myvector.erase(std::remove_if(myvector.begin(), myvector.end(),
std::mem_fn(&std::string::empty)),
myvector.end());
If you have for example vec=["A","","B","C"] and you're delete the element a[1], now 'vec' is long 3 not 4, so vec[3] causes segmentation fault.
Try this:
for (vector<...>::iterator i=myvector.begin();
i != myvector.end(); /* do nothing here */) {
if (i->empty()) {
i=myvector.erase(i);
} else {
++i;
}
}
However Kerrek's solution is more elegant.
First of all, I'm sorry for my English (I'm Brazilian and I'm using the Google translator). But your problem is not exclusively about deleting an item outside the vector, but about accessing its element. Think about the following situation: I have a vector v = {1, 4, 2} and I want to exclude all even numbers using a for and an iterator. When the iterator arrives at the second element (v [2]) it will exclude 4, making the vector {1,2}. But before leaving the for loop, the iterator is still pointing to the second element (v [2]), which is the last element. When it exits, the iterator will be incremented (i ++) and will be equal to v.end (). Therefore, even if it does not give a segmentation fault, the algorithm will not remove all even numbers and, if v was equal to {1,3,4}, it would give the segmentation fault. To fix this, right when you use v.erase (), use i-- (which in the case of your code, which does not directly use the iterator, will work in the same way).Or you can use an increment condition, as in the previous answer, but the iterator needs to be updated correctly.

arithmetic operation on list::iterator?

I got a list like this:
list<float> l;
And I know there are 10 elements in l, I want to take first 7 elements from l and assign them to a vector, so I tried to do it like this:
vector<float> v(l.begin(), l.begin()+7);
The code above can't compile, later I found out that, list doesn't support random access while vector does, so list::iterator doesn't support arithmetic operation?
If so, How could I finish the job mentioned above?
Use copy_n:
v.resize(7);
copy_n(l.begin(), 7, v.begin());

Check if array index exists

Is there any way to check if a given index of an array exists?
I am trying to set numerical index but something like 1, 5, 6,10. And so I want to see if these indexes already exist and if they do just increase another counter.
I normally work with php but I am trying to do this in c++, so basically I am trying to ask if there is an isset() way to use with c++
PS: Would this be easier with vectors? If so, can anyone point me to a good vector tutorial? Thanks
In C++, the size of an array is fixed when it is declared, and while you can access off the end of the declared array size, this is very dangerous and the source of hard-to-track-down bugs:
int i[10];
i[10] = 2; // Legal but very dangerous! Writing on memory you don't know about
It seems that you want array-like behavior, but without all elements being filled. Traditionally, this is in the realms of hash-tables. Vectors are not such a good solution here as you will have empty elements taking up space, much better is something like a map, where you can test if an element exists by searching for it and interpreting the result:
#include <map>
#include <string>
// Declare the map - integer keys, string values
std::map<int, std::string> a;
// Add an item at an arbitrary location
a[2] = std::string("A string");
// Find a key that isn't present
if(a.find(1) == a.end())
{
// This code will be run in this example
std::cout << "Not found" << std::endl;
}
else
{
std::cout << "Found" << std::endl;
}
One word of warning: Use the above method to find if a key exists, rather than something like testing for a default value
if(a[2] == 0)
{
a[2] = myValueToPutIn;
}
as the behavior of a map is to insert a default constructed object on the first access of that key value, if nothing is currently present.
My personal vote is for using a vector. They will resize dynamically, and as long as you don't do something stupid (like try and access an element that doesn't exist) they are quite friendly to use.
As for tutorials the best thing I could point you towards is a google search
To do this without vectors, you can simply cross-check the index you are tying to access with the size of array. Like: if(index < array_size) it is invalid index.
In case the size is not known to you, you can find it using the sizeof operator.
For example:
int arr[] = {5, 6, 7, 8, 9, 10, 1, 2, 3};
int arr_size = sizeof(arr)/sizeof(arr[0]);
It sounds to me as though really a map is closest to what you want. You can use the Map class in the STL (standard template library)(http://www.cppreference.com/wiki/stl/map/start).
Maps provide a container for objects which can be referenced by a key (your "index").