This question already has answers here:
allocating vectors (or vectors of vectors) dynamically
(9 answers)
Closed 8 years ago.
what is the best way to define 2D vector, which rows are known? So basically, I will have something like this:
2 3 4
7 5 4 12 4
2 1 0 2
I will know how many rows there are (well actuall I will know it only after getting row variable), but each row collumn will vary. So what is the best way to do this? (I am planning on pushing back each row's columns when I will need, if it is possible)
Here is someone who had a similar question http://www.cplusplus.com/forum/beginner/12409/. Just Define a vector of vectors.
It wont let me comment down below, but in your code you have tiesiogiaiJungiasi[A.at(i)]
What type is A and if it is a vector then is that vector filled with integers if not A.at(i) is your problem. That will give you the element that is at that location not the location itself.
If you are trying to push the element index i from row B into the element index i of row A try something like this.
tiesiogiaiJungiasi[A].push_back(tiesiogiaiJungiasi[B][i]);
assuming there is an element in row B at the index location.
Another problem could be that you say that your rows may be of different sizes. Well you should look at your m parameter in the for loop then. If that number is larger than the number of columns (elements) in that row i has the possibility of walking off the array.
If i'm understanding correctly, this seems like what you want is an array of vectors. You can set an array of vectors like vector<string> myArray[3]; and then push values into myArray[0], myArray[1], etc.
If I understood correctly. You want a data structure that will allow you to append to the end of each row. A vector< vector < int > > will do.
vector< vector < int > > rows;
You have to populate this, if you know the max number of rows you could write:
vector< vector < int > > rows(MAX);
You append to the end of a row using rows[i].push_back(...);. Rows are numbered starting at 0 (add 1 to MAX if you want to start at 1).
Related
Is there any other way to access or retrieve the data/values that are in vector at a specific index through the size of the vector? I am currently looping through the vector starting at a desired index all the way to the size of vector or stopping at
lets say the values in the vector include 1 2 3 4 5 6 7 8
and I want to retrieve 3 4 5 6 7 8.
Is there any other way of sufficient way to obtain these values other than looping through the vector?
If you are trying to access and operate on values at index 2 through index 7, (3 4 5 6 7 8)
then looping through the vector to retrieve the values is the most efficient way. If you are trying to group this sub-data and keep a hard copy of your original vector then looping is still most efficient.
Example 1
std::vector<int> myVec{1,2,3,4,5,6,7,8};
for (int i = 2; i < vec.size(); i++)
{
// Do your operation on myVec[i]
// Push myVec[i] to a new list ?
}
If you are trying to obtain a new vector from your original vector which contains only the values you are interested in, then there is a better way. Note that the values 1 and 2 are now lost.
Example 2
myVec.erase (myVec.begin(),myVec.begin() + 2);
//myVec[0] now contains 3
//myVec.size() == 6
Putting Examples 1 and 2 together, if you are trying to obtain a new vector with the values at index 2 through index 7, you can use the assignment operator (=) to assign the data from an existing vector to a new one. Note that this is actually not any more efficient than looping through the vector yourself, but might look a little cleaner. After doing this then you can reference Example 2 to edit the new vector to your liking.
Recently I've come into a wall, because I have no idea how to count the occurrences in one 2d array from another 2d array. For example, if I have
int winning_nums[3][6]; // random generated numbers array
and
int array[7][7]; // Sorted array from 1 to 49
I need to get all occurrences of each number in winning_nums to all the elements in array.For example: If I got 1 array of winning_nums that equals 6 size, 1 2 3 4 5 6 needs to be checked if they are occuring in array, like for each row in winning_nums.
I've tried to sort it out, like sort the winning_nums array, and then try to occur it with two additional for loops.
Any better ideas? Anything is welcomed.
So I am pretty new to c++ and I am not sure if there is a data structure already created to facilitate what I am trying to do (so I do not reinvent the wheel):
What I am trying to do
I am reading a file where I need to parse the file, do some calculations on every floating value on every row of the file, and return the top 10 results from the file in ascending order.
What am I trying to optimize
I am dealing with a 1k file and a 1.9 million row file so for each row, I will get a result that is of size 72 so in 1k row, I will need to allocate a vector of 72000 elements and for the 1.9 million rows ... well you get the idea.
What I have so far
I am currently working with a vector for the results which then I sort and resize it to 10.
const unsigned int vector_space = circularVector.size()*72;
//vector for the results
std::vector<ResultType> results;
results.reserve(vector_space);
but this is extremely inefficient.
*What I want to accomplish *
I want to only keep a vector of size 10, and whenever I perform a calculation, I will simply insert the value into the vector and remove the largest floating point that was in the vector, thus maintaining the top 10 results in ascending order.
Is there a structure already in c++ that will have such behavior?
Thanks!
EDIT: Changed to use the 10 lowest elements rather than the highest elements as the question now makes clear which is required
You can use a std::vector of 10 elements as a max heap, in which the elements are partially sorted such that the first element always contains the maximum value. Note that the following is all untested, but hopefully it should get you started.
// Create an empty vector to hold the highest values
std::vector<ResultType> results;
// Iterate over the first 10 entries in the file and put the results in the vector
for (... ; i < 10; i++) {
// Calculate the value of this row
ResultType r = ....
// Add it to the vector
results.push_back(r);
}
// Now that the vector is "full", turn it into a heap
std::make_heap(results.begin(), results.end());
// Iterate over all the remaining rows, adding values which are lower than the
// current maximum
for (i = 10; .....) {
// Calculate the value for this row
ResultType r = ....
// Compare it to the max element in the heap
if (r < results.front()) {
// Add the new element to the vector
results.push_back(r);
// Move the existing minimum to the back and "re-heapify" the rest
std::pop_heap(results.begin(), results.end());
// Remove the last element from the vector
results.pop_back();
}
}
// Finally, sort the results to put them all in order
// (using sort_heap just because we can)
std::sort_heap(results.begin(), results.end());
Yes. What you want is a priority queue or heap, defined so as to remove the lowest value. You just need to do such a remove if the size after the insertion is greater than 10. You should be able to do this with STL classes.
Just use std::set to do that, since in std::set all values are sorted from min to max.
void insert_value(std::set<ResultType>& myset, const ResultType& value){
myset.insert(value);
int limit = 10;
if(myset.size() > limit){
myset.erase(myset.begin());
}
}
I think MaxHeap will work for this problem.
1- Create a max heap of size 10.
2- Fill the heap with 10 elements for the first time.
3- For 11th element check it with the largest element i.e root/element at 0th index.
4- If 11th element is smaller; replace the root node with 11th element and heapify again.
Repeat the same steps until the whole file is parsed.
for(myIterator = numbers.begin();myIterator != numbers.end() ;myIterator++)
{
resultVect.push_back(*myIterator+2);
numbers.erase(myIterator+2);
}
numbers consist of a series of numbers (eg 1,2,3,4,5,6,7)
Then I would like to erase every 3rd number.
Something like,
1 2 3 4 5 6 ( First round -> 3 is out)
1 2 4 5 6 ( Second round -> 6 is out)
1 2 4 5 ( Third round -> 4 is out)
and so on.
I will store the number that goes out in another vector (resultVect).
Im getting Assertion error. Pls advise tq
When you use erase for a vector, it will relocate the elements after the erase position so the iterators after that will be invalidated.
Second when you say iterator + 2 and that could go beyond the range of the vector too.
Removing an element from the vector invalidates all iterators to that element and beyond (in the current standard, there is an open issue to change this).
The first question is how efficient you want the process to be, if you don't care (much) about performance you can do a simple loop:
for (int i = 3; i < input.size(); i+=3) {
result.push_back(input[i]);
}
for (int i = (input.size()+2)/3 - 1; i >= 0; --i) {
input.erase(input.begin()+i*3);
}
If performance is critical, you can take a look at the std::remove algorithm and use the same approach to avoid doing multiple copies of the elements while you run the algorithm. Basically you need a read and a write head into the original container and you only copy from the read to the write location if the condition is not met.
Simply put: you cannot modify a vector while iterating it. The iterator will become invalid and that will get you an assertion.
To properly do what you want, you might consider creating a copy of the vector with values to keep, and a vector with values to remove. Then replace the number vector by the one with the values to keep.
I'm working on a program to solve the n queens problem (the problem of putting n chess queens on an n x n chessboard such that none of them is able to capture any other using the standard chess queen's moves). I am using a heuristic algorithm, and it starts by placing one queen in each row and picking a column randomly out of the columns that are not already occupied. I feel that this step is an opportunity for optimization. Here is the code (in C++):
vector<int> colsleft;
//fills the vector sequentially with integer values
for (int c=0; c < size; c++)
colsleft.push_back(c);
for (int i=0; i < size; i++)
{
vector<int>::iterator randplace = colsleft.begin() + rand()%colsleft.size();
/* chboard is an integer array, with each entry representing a row
and holding the column position of the queen in that row */
chboard[i] = *randplace;
colsleft.erase(randplace);
}
If it is not clear from the code: I start by building a vector containing an integer for each column. Then, for each row, I pick a random entry in the vector, assign its value to that row's entry in chboard[]. I then remove that entry from the vector so it is not available for any other queens.
I'm curious about methods that could use arrays and pointers instead of a vector. Or <list>s? Is there a better way of filling the vector sequentially, other than the for loop? I would love to hear some suggestions!
The following should fulfill your needs:
#include <algorithm>
...
int randplace[size];
for (int i = 0; i < size; i ++)
randplace[i] = i;
random_shuffle(randplace, randplace + size);
You can do the same stuff with vectors, too, if you wish.
Source: http://gethelp.devx.com/techtips/cpp_pro/10min/10min1299.asp
Couple of random answers to some of your questions :):
As far as I know, there's no way to fill an array with consecutive values without iterating over it first. HOWEVER, if you really just need consecutive values, you do not need to fill the array - just use the cell indices as the values: a[0] is 0 and a[100] is 100 - when you get a random number, treat the number as the value.
You can implement the same with a list<> and remove cells you already hit, or...
For better performance, rather than removing cells, why not put an "already used" value in them (like -1) and check for that. Say you get a random number like 73, and a[73] contains -1, you just get a new random number.
Finally, describing item 3 reminded me of a re-hashing function. Perhaps you can implement your algorithm as a hash-table?
Your colsleft.erase(randplace); line is really inefficient, because erasing an element in the middle of the vector requires shifting all the ones after it. A more efficient approach that will satisfy your needs in this case is to simply swap the element with the one at index (size - i - 1) (the element whose index will be outside the range in the next iteration, so we "bring" that element into the middle, and swap the used one out).
And then we don't even need to bother deleting that element -- the end of the array will accumulate the "chosen" elements. And now we've basically implemented an in-place Knuth shuffle.