ive defined the following and filled it with elements:
vector <vector<double> > my_vector;
but i want a delete an element with a specific key...
my_vector.erase(int(specific_key));
but it doesnt allow me. how would i properly dispose of the elements assigned to that key properly?
Assuming by specific_key you mean the element at that position in the vector:
my_vector.erase(my_vector.begin() + specific_key);
Would be the "most correct" answer.
If you meant to delete the element that matches specific_key (which will have to be of type vector<double> in the given example:
my_vector.erase(find(my_vector.begin(), my_vector.end(), specific_key));
erase takes in an iterator as argument.
You can do
my_vector.erase (my_vector.begin() + specific_key);
You can also pass in a range
my_vector.erase (my_vector.begin(), my_vector.begin() + 2);
One thing that you should note is that the size of the vector also gets reduced.
The erase method takes iterators as their argument.
Example
If Specific key is not position and say its some data in vector, then one has to iterate vector for that data and erase particular iterator.
Related
Context: I am implementing the Push-Relable Algorithm for MaxFlow in a network and want to keep track of labels of all nodes, for each possible label (2*V-1 many) I want to have a doubly-linked list containing the nodes with that label.
So I have a vector where each entry is a list. Now I need to delete an element from one list and move it into another list in another vector-entry.
In order to do so, I use an vector (wich size is equal to the number of elements) where each entry is an interator, so I always know the position of each element.
Before implementing it on a bigger scale I wanted to try whether it works at all. So I create the two vectors, add one element into a list, store the iterator in the other vector and try to delete that element again.
But the std::vector::erase() method always gets me SegFaults. Did I miss something?
int V=50;
int i=0, v=42;
vector<list<int> > B(2*V-1);
vector<list<int>::iterator> itstorage(V) ;
B[i].push_back(v);
itstorage[v]=B[i].end();
B[i].erase(itstorage[v]);
B[i].end() does not refer to the last item you pushed, it is one past the item you pushed.
What you want is:
std::list<int>::iterator p = B[i].end();
--p;
Alternatively, instead of using push_back, you could use the insert member function which returns an iterator to the newly inserted item.
itstorage[v] = B[i].insert(B[i].end(), v);
I need to insert an object to existing vector of objects. I know that i need to use iterator to do it but i dont know how it exactly works.
I have alphabetically sorted vector and i need to insert new object by its name in exact index that i got after some search . So i have this.
vector<Person>people;
int index =54;
Person temp;
people.push_back(temp);//insert at end of vector
people.insert(index, temp);//doesnt work for int
Can anyone help me how to use iterator properly to insert my object to 54th index of vector and move all following object by one index ?
Thank you for any help.
The straight forward answer is you need an iterator. The iterator for std::vector supports random access, which means you can add or subtract an integer value to or from an iterator.
people.insert(people.begin() + index, temp);
The better answer is don't use an index, use an iterator. What is your loop? You should be able to refactor the loop to use an iterator instead of an index.
I have alphabetically sorted vector and i need to insert new object by its name in exact index that i got after some search.
If the vector is sorted alphabetically, then the proper way of inserting an item in the correct position while maintaining the sort order is using the upper_bound function:
people.insert(upper_bound(people.begin(), people.end(), temp), temp);
The function searches the sorted range, and returns the position of the first element that is greater than temp.
Here is a demo on ideone.
Solution:
vector<Person>::iterator iter = people.begin() + index;
people.insert(iter, temp);
Reference:
std::vector::insert()
RandomAccessIterator
I am trying to build a program that uses the second to last element in a vector, so far I've used:
(arr2.rbegin()+1)
If I use a comparison operator in a conditional such as:
if(arr2.rbegin()+1 == true)
I get an error message: no match for operator ==
Many of the answers and comments have the right idea but really ugly syntax. Here are two nice ways to express that.
arr2.end()[-2] // end() is past the last element, -1 for last element, -2 for second-last
arr2.rbegin()[1] // rbegin() is reverse order starting at 0 for last element, 1 for second-last
Demo: http://ideone.com/2cZeUq
It works because RandomAccessIterator, which vector has, is required to provide operator[] such that it[n] is equivalent to *(it + n), just like for pointers.
So the code in your question becomes just
if (arr2.rbegin()[1]) // test penultimate element
looking at the documentation here
http://www.cplusplus.com/reference/vector/vector/?kw=vector
I'd expect you to access your element by
secondToLast = myVector[myVector.size() - 2];
You can try doing like this:-
if(*(arr2.rbegin()+1))
Sometimes there might be less than 2 items in the list, so myVector.size() - 2 or other direct accessors will throw an error. I've done the following . . .
if (myVector.size() > 1)
{
secondToLast = myVector[myVector.size() - 2];
}
It depends on what you mean by "second to last element". Take the following iterator definition...
vector<int>::iterator it = arr2.end();
it--;
it--;
You have to decriment the iterator twice because when you declare the iterator to "point" to the end, it actually references the location AFTER the last element in the vector.
Dont forget that when you want the value that the iterator points to, you have to dereference it. like so...
cout << *it;
Mostly for lulz, but if your elements are non-scalar and you need to access a member of the element in question, you can use the ++-> construction:
std::vector<std::pair<int, int>> arr = ...;
auto grug = arr.rbegin()[1].first;
auto leet = arr.rbegin()++->first;
assert(grug == leet);
The way it works is we post-increment the iterator returned by rbegin() with ++ and then access it with ->. It is actually superior to the clearest [1] form in the sense it will work on any iterator, not only random access iterator.
Post it on review and get some popcorn.
There are many ways you can access elements from the back
one you can use is the back property that comes with std::vector container
and if you want to access an element from the back (either last element or up to n)
you can do this
std::vector vec{1,2,3};
int lastsecond = vec.back()-1; will give you -> 2;
you can check vector properties which there is a decent bit.
https://en.cppreference.com/w/cpp/container/vector
I want to get the last element of the vector and then assign it to a string but I seem to have problems.
Imagine this vector has already been filled but I do not know how much so I tried to do this.
std::vector<std::string> vec;
std::string s = vec.end();
Would a loop work and then just get the last index ?
This did not work so is there a way to get the end of a vector?
EDIT------
out.push_back(r.validateR(str));
appendCustomizedOutput = out.back();
DCS_LOG_DEBUG("END " << appendCustomizedOutput);
split(test,appendCustomizedOutput,boost::is_any_of("\n"));
DCS_LOG_DEBUG("END " << test[0]);
When i try to print test[0] nothing is printed and i do not know why ?
vector::end() returns an iterator that is one beyond the last real element in the vector (it's used primarily for checking while iterating).
Best way would be:
std::string s = vec.back(); // last item
As #JamesKanze and #PeterWood says, don't forget to check for empty vector - else it's undefined behaviour...
That's what vec.back() is for. Just make sure that the vector isn't empty first.
Use vec.back()to get a reference to the last element. Use vec.pop_back()to remove the last element (without returning it).
container.end() (or whatever kind of container) will return an iterator to the end of the container. To get the last item in the container, you want container.back() instead:
std::string s = vec.back();
end() returns an iterator referring to the past-the-end element in the vector container.
You need back(): it returns a reference to the last element in the vector container.
At the moment my solution is to iterate through the map to solve this.
I see there is a upper_bound method which can make this loop faster, but is there a quicker or more succinct way?
The end:
m.rbegin();
Maps (and sets) are sorted, so the first element is the smallest, and the last element is the largest. By default maps use std::less, but you can switch the comparer and this would of course change the position of the largest element. (For example, using std::greater would place it at begin().
Keep in mind rbegin returns an iterator. To get the actual key, use m.rbegin()->first. You might wrap it up into a function for clarity, though I'm not sure if it's worth it:
template <typename T>
inline const typename T::key_type& last_key(const T& pMap)
{
return pMap.rbegin()->first;
}
typedef std::map</* types */> map_type;
map_type myMap;
// populate
map_type::key_type k = last_key(myMap);
The entries in a std::map are sorted, so for a std::map m (assuming m.empty() is false), you can get the biggest key easily: (--m.end())->first
As std::map is assosiative array one can easily find biggest or smallest key very easily. By defualt compare function is less(<) operator so biggest key will be last element in map. Similarly if someone has different requirement anyone can modify compare function while declaring map.
std::map< key, Value, compare< key,Value > >
By default compare=std::less
Since you're not using unordered_map, your keys should be in order. Depending upon what you want to do with an iterator, you have two options:
If you want a forwards-iterator then you can use std::prev(myMap.end()). Note that --myMap.end() isn't guaranteed to work in all scenarios, so I'd usually avoid it.
If you want to iterate in reverse then use myMap.rbegin()
Since the map is just an AVL tree then, it's sorted -in an ascending order-. So, the element with largest key is the last element and you can obtain it using one of the following two methods:
1.
largestElement = (myMap.rbegin())-> first; // rbegin(): returns an iterator pointing to the last element
largestElement = (--myMap.end())->first; // end(): returns an iterator pointing to the theortical element following the last element