Insert object at index of vector c++ - c++

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

Related

Reallocating Iterators [REWRITTEN]

How would you insert at a certain location in an STL vector?
So far, I have tried inserting into an STL vector like so:
someVector.insert(someVector.begin() + location, info);
This works when I'm inserting items in sequence, but when I delete an item from the vector, I want to be able to insert at that location. However, the iterator needs to be reallocated since it throws a "vector iterator + offset out of range" error. (I'm pretty new to C++ iterators, so I'm not entirely sure what "iterator reallocation" is and can't seem to find a good explanation, so if you can explain, please feel free!) I can find a lot of questions that ask when the iterator needs to be reallocated but not on the best way to do so. Alternatively, would there be a different/better way to insert at a position?
The erase operation on a vector returns the iterator one past the just-erased element. You can use that iterator as the subsequent insertion position to insert "at the place" where you erased:
auto it = v.begin() + 3; // say
it = v.erase(it); // erase and store position
v.insert(it, -3); // insert at that position

Storing and managing std::list::iterator

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);

How to do fast sorting in sorted list when only one element is changed

I need a list of elements that are always sorted. the operation involved is quite simple, for example, if the list is sorted from high to low, i only need three operations in some loop task:
while true do {
list.sort() //sort the list that has hundreds of elements
val = list[0] //get the first/maximum value in the list
list.pop_front() //remove the first/maximum element
...//do some work here
list.push_back(new_elem)//insert a new element
list.sort()
}
however, since I only add one elem at a time, and I have speed concern, I don't want the sorting go through all the elements, e.g., using bubble sorting. So I just wonder if there is a function to insert the element in order? or whether the list::sort() function is smarter enough to use some kind of quick sort when only one element is added/modified?
Or maybe should I use deque for better speed performance if above are all the operations needed?
thanks alot!
As mentioned in the comments, if you aren't locked into std::list then you should try std::set or std::multiset.
The std::list::insert method takes an iterator which specifies where to add the new item. You can use std::lower_bound to find the correct insertion point; it's not optimal without random access iterators but it still only does O(log n) comparisons.
P.S. don't use variable names that collide with built-in classes like list.
lst.sort(std::greater<T>()); //sort the list that has hundreds of elements
while true do {
val = lst.front(); //get the first/maximum value in the list
lst.pop_front(); //remove the first/maximum element
...//do some work here
std::list<T>::iterator it = std::lower_bound(lst.begin(), lst.end(), std::greater<T>());
lst.insert(it, new_elem); //insert a new element
// lst is already sorted
}

Erasing a vector element by key

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.

C++ How to find the biggest key in a std::map?

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