I've got a function that uses a 2d string type vector. The function should read data from a file, store it into vector A and push back A into B. Then, the loop gets new values for A, which should overwrite the previous ones. How am I supposed to do this? Is there any way to "reset" the vector, so that vector.push_back() inserts data from the beggining, instead of attaching it to the end?
Simply use a single dimension vector of std::strings and just use std::vector::clear to remove the old content before std::vector::inserting the next.
Notice that clear just removes all the elements, but leaves the capacity unchanged.
If you really have to keep the 2 dimention vector, then just apply what I said to vector[0] or any generic vector[i] vector you may need to work on.
Related
I am to write a C++ program that :
"Implements the vector ADT by means of an extendable array used in a circular fashion, so that insertions and deletions at the beginning and end run in constant time. (So not O(n)). Print the circular array before and after each insertion and deletion, You cannot use the STL."
This task seems very confusing to me. A std::vector is implemented using a dynamic array that is based off the concept of a stack, correct? Performing a deletion or insertion at the front seems to me that this should be implemented as a Queue or maybe a Dequeue, not a Vector. Also, a circular array would mean that when data is pushed onto an array that is Full, old data becomes overwritten, right? So when should I know to expand the vector's capacity?
If I'm not making sense here, Basically I need help in understanding how I should go about implementing a dynamic circular array..
Yes, this is a homework assignment. No, I do not expect anyone to provide code for me, I only wish for someone to give me a push in the right direction as to how I should think about implementing this. Thank you.
I think you are actually being asked to implement deque. The point of the "circularity" is that in normal vector you cannot add an element at the beginning since there is no free space and you would have to move all other elements to the right. So what you can do is you simulate a circle by putting the element to the end the base array and remember that's where the first element is.
Example: 2, 3, -, -, 1 where 1 is first and 3 is last
So, basically you insert elements circullary, and remember where the first and the last elements are so you can add to beginning/end in O(1). Also when the array is full, you have to move all the elements to a larger one. If you double the size, you still get amortized time of O(1)
1) m_nextIn and m_nextOut - data attributes of class queue;
I find it useful to have two integers, with label m_nextIn and m_nextOut ... these identify where in the circular array you 'insert' the next (i.e. youngest) obj instance into the queue, and where you 'delete' the oldest obj instance from the queue.
These two items also provide constant time insert and delete.
Don't get confused as to where the beginning or end of the queue is. The array starts at index 0, but this is not the beginning of your queue.
The beginning of your queue is at nextIn (which probably is not 0, but may be). Technique also known as round-robin (a research term).
2) empty and full - method attributes
Determining queue full / empty can be easily computed from m_nextIn and m_nextOut.
3) extendable
Since you are prohibited from using vector (which itself is extendable) you must implement this functionality yourself.
Note about your comment: The "dynamic memory" concept is not related to stack. (another research term)
Extendable issues occur when your user code invokes the 'insert' AND the array is already full. (capture this test effort) You will need to detect this issue, then do 4 things:
3.1) allocate a new array (use new, and simply pick an appropriate size.)
Hint - std::vector() doubles it's capacity each time a push_back() would overflow the current capacity
3.2) transfer the entire contents of the array to the new array, fixing all the index's as you go. Since the new array is bigger, just insert trivially.
3.3) delete the old array - i.e. you copied from the old array to the new array, so do you 'delete' them? or simply delete the array?
3.4) finish the 'insert' - you were in the middle of inserting another instance, right?
Good luck.
I am trying to shuffle a list by copying it to a vector first and then back to the empty list.
vector<Agent*> tmpVector(agents_.size());
copy(agents_.begin(), agents_.end(), tmpVector.begin());
random_shuffle(tmpVector.begin(), tmpVector.end());
agents_.clear();
copy(tmpVector.begin(), tmpVector.end(),agents_.begin());
The program crashes with a run-time error: list iterator not dereferencable
1- What is wrong with the code.
2- The list contains pointers. I assume nothing would go wrong if the above approach works (because pointer values won't change and the allocated variables can still be referenced with them later) , right?
thanks.
I think the issue is in these two lines:
agents_.clear();
copy(tmpVector.begin(), tmpVector.end(),agents_.begin());
This first line clears out the agents_ list, so it's now empty. The next line then tries to replace the sequence of elements stored in agents_ starting at the first element with the contents of the range [tmpVector.begin(), tmpVector.end()). This causes undefined behavior, because there are no elements in the list.
To fix this, try removing the call to agents_.clear() from the previous line. This will cause the copy call to overwrite the existing elements in the agents_ list with the appropriately shuffled values.
Hope this helps!
When you clear() the tmp array you set its size to zero.
The copy expects the destination to have enough space already set up (ie the size must be correct).
The first alternative is to use back inserter:
agents_.clear();
std::copy(tmpVector.begin(), tmpVector.end(), std::back_inserter(agents_));
But since you are using pointers in the destination.
It will copy over them with no problem. So it is probably easier to just remove the clear.
// agents_.clear();
// The copy will copy over the old values with no problems.
copy(tmpVector.begin(), tmpVector.end(),agents_.begin());
The problem comes from the last two lines:
agents_.clear();
copy(tmpVector.begin(), tmpVector.end(),agents_.begin());
Specifically, you call clear() on the list, which destroys all elements and leaves the list with a size of 0, and then try to access begin(). Trying to dereference begin() then turns into undefined behaviour.
You can clean this code up quite a bit:
vector<Agent*> tmpVector(agents_.begin(), agents_.end());
random_shuffle(tmpVector.begin(), tmpVector.end());
copy(tmpVector.begin(), tmpVector.end(),agents_.begin());
Will do what you want. The first copy in unnecessary, vector has a constructor taking 2 iterators you can use in this case.
I've searched around the internet, and I can't seem to find the answer to my solution (or I'm blind/dumb and just can't figure out how to do it). Part of one of my assignments is as follows:
Constructor – creates an empty 2xn dynamic array. Your dynamic array should start as 2x5 in size but can grow to any length. The default value for empty `elements is “empty” and 0. The class should also have a nextElement variable that keeps track of the next empty spot in the array and is increment each time a data element is added.
Is there a way to create a 2*5 array that will accept string in one of the dimensions and integers in the other?
I'm wondering whether somebody can help me with this problem. I'm using C/C++ to program and I need to do the following:
I am given a sorted array P (biggest first) containing floats. It usually has a very big size.. sometimes holding correlation values from 10 megapixel images. I need to iterate through the array until it is empty. Within the loop there is additional processing taking place.
The gist of the problem is that at the start of the loop, I need to remove the elements with the maximum value from the array, check certain conditions and if they hold, then I need to reinsert the elements into the array but after decreasing their value. However, I want the array to be efficiently sorted after the reinsertion.
Can somebody point me towards a way of doing this? I have tried the naive approach of re-sorting everytime I insert, but that seems really wasteful.
Change the data structure. Repeatedly accessing the largest element, and then quickly inserting new values, in such a way that you can still efficiently repeatedly access the largest element, is a job for a heap, which may be fairly easily created from your array in C++.
BTW, please don't talk about "C/C++". There is no such language. You're instead making vague implications about the style in which you're writing things, most of which will strike experienced programmers as bad.
I would look into the http://www.cplusplus.com/reference/stl/priority_queue/, as it is designed to do just this.
You could use a binary search to determine where to insert the changed value after you removed it from the array. Note that inserting or removing at the front or somewhere in the middle is not very efficient either, as it requires moving all items with a higher index up or down, respectively.
ISTM that you should rather put your changed items into a new array and sort that once, after you finished iterating over the original array. If memory is a problem, and you really have to do things in place, change the values in place and only sort once.
I can't think of a better way to do this. Keeping the array sorted all the time seems rather inefficient.
Since the array is already sorted, you can use a binary search to find the location to insert the updated value. C++ provides std::lower_bound or std::upper_bound for this purpose, C provides bsearch. Just shift all the existing values up by one location in the array and store the new value at the newly cleared spot.
Here's some pseudocode that may work decently if you aren't decreasing the removed values by much:
For example, say you're processing the element with the maximum value in the array, and say the array is sorted in descending order (largest first).
Remove array[0].
Let newVal = array[0] - adjustment, where adjustment is the amount you're decreasing the value by.
Now loop through, adjusting only the values you need to:
Pseudocode:
i = 0
while (newVal < array[i]) {
array[i] = array[i+1];
i++;
}
array[i] = newVal;
swap(array[i], array[i+1]);
Again, if you're not decreasing the removed values by a large amount (relative to the values in the array), this could work fairly efficiently.
Of course, the generally better alternative is to use a more appropriate data structure, such as a heap.
Maybe using another temporary array could help.
This way you can first sort the "changed" elements alone.
And after that just do a regular merge O(n) for the two sub-arrays to the temp array, and copy everything back to the original array.
i have a doubt on following case;
suppose i want to define a vector of vector to acomadate set of elements and i can add the data and can be used those elemnts to compute something else. then i dont want that vector anymore. then later, suppose if i want to accomadae another set of data as a vector of vector, then i can reuse the previously created variable, then;
(1) if I created my vector of vector as dynamic memory and deleted as
vector<vector<double> > *myvector = new vector<vecctor<double> >;
//do push back and use it
delete myvector;
and then reuse again
(2) if I created my vector of vector as simply
vector<vector<double> > myvector;
//do push back and use it
myvector.clear();
and then reuse again
but, i guess in both method very few memory is remaining though we have removed it. so, i would like to know what is the efficient method to defin this vector of vector.
(3) if the size of the inside vector is always 2, then is it still efficient to use
vector of vector by defining
vector<vector<double> > myvector(my_list.size(), vector<double>(2)) other than another container type
(4) if i use predefined another class to hold inside 2 elements and then take a vector of those object type as (for example XY is the class which can hold 2 elements, may be as an array)
vector<XY>;
i hope, please anyone comment me what would be the most efficient method (from 1-4) interms of speed and memory needed. is there any better ways, plz suggest me too. thanks
If you only need two elements the most efficient way is probably:
std::vector<std::tr1::array<double, 2>> myvector;
// or std::vector<std::pair<double, double>> myvector;
// use it
myvector.clear(); // This will not deallocate any memory, so what has alrdy been allocated will be used for future push_backs
If this is homework (or not) and you want to know which is faster then you should try it: run the "push back and clear" or "new and delete" in a loop a few million times and time the execution. I suspect 2. will be a bit faster.
You say you want to accommodate a set of elements, and that the size of the inner vector is 2.
That is a bit ambiguous, but you can further examine 2 things:
1. std::pair, if your "element" contains 2 other "things"
2. std::map, if you want to reference of of the "elements" based on the value of another "element"