I have the following matrix:
unsigned wins[8][3] = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, { 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 }, { 0, 4, 8 }, { 2, 4, 6 } };
how to convert it into a std::vector?
You can use the two iterator constructor to instantiate a vector with a copy of of the data in wins:
unsigned* start = &wins[0][0];
std::vector<unsigned> vwins(start, start + (8 * 3));
This relies on pointer arithmetic, the fact that pointers are iterators, and the fact that 2D arrays are contiguous blocks, essentially 1D arrays with clever indexing.
Since I don't know whether you want a 2D vector or not, I'll handle the 2D case since juanchopanza handled the 1D case. :) If you're using C++11, then you can just do this:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<vector<int>> wins = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, { 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 }, { 0, 4, 8 }, { 2, 4, 6 } };
for(vector<int> & row : wins) {
for(int &col : row) {
cout << col << " ";
}
cout << endl;
}
return 0;
}
This example uses C++11 initializer lists to create an analogous structure, also called wins. I also wrote a little code to show how you could loop through it to print it out in a sensical order.
Hope this helps! :)
Related
I'm currently trying to find the minimum element of a 2D vector. I'm trying to practice using C++11 lambda functions and figured this might be good practice, but can't seem to get it compiling.
I'm aware that I could do the following:
vector<vector<int>> matrix = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10 },
{5, 6, 8, 1, 12 },
{1, 7, 2, 4, 18 },
};
int result = std::numeric_limits<int>::max();
for(const auto& row : matrix)
{
int minElemInRow = *std::min_element(row.begin(), row.end());
result = std::min(result , minElemInRow);
}
return result;
but was wondering if the same could be done with a lambda function. Currently, this is my best attempt:
vector<vector<int>> matrix = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10 },
{5, 6, 8, 1, 12 },
{1, 7, 2, 4, 18 },
};
return *std::min_element(matrix.begin(), matrix.end(),
[](const auto& row)
{
return *std::min_element(row.begin(), row.end());
});
I get the error: error C2672: 'operator __surrogate_func': no matching overloaded function found
How I feel it should be working is that the outer min_element will pass in a row at a time (which is just a reference to a vector), from which I can return the smallest, which will then be compared against other rows.
I thought that the problem might be that the lambda would be receiving an iterator to a vector of ints rather than a reference to the vector of ints, but dereferencing doesn't seem to be helping.
Is there a better way to be doing what I'm trying to do?
#assembly_wizard pointed out that min_element wants a predicate which can compare two of the item passed it. That is two rows. This leads to the following code:
vector<vector<int>> matrix = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10 },
{5, 6, 8, 1, 12 },
{1, 7, 2, 4, 18 },
};
auto i = std::min_element(matrix.begin(), matrix.end(),
[](const auto& lhs, const auto& rhs)
{
return *std::min_element(lhs.begin(), lhs.end()) <
*std::min_element(rhs.begin(), rhs.end());
});
This will find the row with the smallest element. Though I can make that work by wrapping it in yet another std::min_element, that's getting way more complex than to be remotely helpful. If anyone has a better suggestion, I'd love to hear it!
I've compiled a working version that does what I've mentioned in the comments:
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<std::vector<int>> matrix = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10 },
{5, 6, 8, 1, 12 },
{1, 7, 2, 4, 18 },
};
std::vector<int> row_minimums(matrix.size());
std::transform(matrix.begin(), matrix.end(), row_minimums.begin(), [](const auto& row) {
return *std::min_element(row.begin(), row.end());
});
auto i = *std::min_element(row_minimums.begin(), row_minimums.end());
std::cout << "Minimum element is: " << i << std::endl;
}
See it in action on godbolt
This will take the minimum of each row separately, so we get row_minimums which is a vector of ints, and then it takes the minimum of these to get the final result between all the rows.
The only thing making this code worse than the for loop version, is that it keeps all of the row_minimums in memory at once, before running min_element on them. Unfortunately I don't know of a way to do this simultaneously, but I'm not the greatest STL expect, so maybe there is a way.
Other options you might consider is first concatenating the 2D matrix into a 1D vector and then using min_element on it, or the option you've included in your edit where you call min_element 3 times.
Also, this SO answer seems to have interesting info regarding solutions using the boost library which might be better, but I'm not sure exactly what they are.
Just a little simpler:
With std::for_each you iterate over each vector in matrix, and obtain the minimum element of them. As min is captured by reference, you get the min of all of them.
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<std::vector<int>> matrix = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10 },
{5, 6, 8, 1, 12 },
{1, 7, 2, 4, 18 },
};
int min = std::numeric_limits<int>::max();
std::for_each(matrix.begin(), matrix.end(),
[&min](const auto& v)
{
min = std::min(*min_element(v.begin(), v.end()), min);
}
);
std::cout << "Minimum element is: " << min << std::endl;
}
I am trying to store a cell-like structure in C++, where its elements can have arrays of different lengths like the following example:
myMultiSizedArray = {
{ 1, 2, 4 },
{ 3, 5, 6, 7 },
{ 7, 8, 9, 10 },
{ 1, 3 },
{ 4, 5, 8 },
{ 9, 10 }
{ 5 } }
I am thinking of using a vector in a struct such as the following:
struct f
{
std::vector<int> elements;
};
std::vector<f> myMultiSizedArray;
I would appreciate it if the community could give me their feedback. Are there better, more efficient approaches? Does C++ provide a means for this? Thank you
As mentioned by other users as comment, you could use a vector inside another vector as in piece of code below:
using namespace std;
vector<vector<int>> myMultiSizedArray;
myMultiSizedArray.push_back({ 1, 2, 3, 4 });
myMultiSizedArray.push_back({ 6, 5, 200, 3, 2, 1 });
use "vector< vector< int > >" is better
I have a function declaration as follows
void set_values(float values[4][4]);
If I call the function like this everything is OK.
float values[4][4] = {
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 }
};
mat1.set_values(values);
However i thought that I could take the array declared in the curly braces and pass it directly into the function like this:
mat1.set_values({
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 }
});
But this gives me a compile error too many initializer values
Why does the first code work but not the second one?
Your function expects an array object, not an initialization list for such an object.
Im using VS2013 along with the SystemC library from Allegro. I was trying to initialize two arrays as follows:
int pathObs1[19] = {10,9,8,7,6,5,4,3,2,1,2,3,4,5,6,7,8,9,10};
int Map[10][4] = {
{ 0, 3, 1, 4 }, //Grid 1
{ 1, 3, 2, 4 }, //Grid 2
{ 2, 3, 3, 4 }, //Grid 3
{ 3, 3, 4, 4 }, //Grid 4
{ 4, 3, 5, 4 }, //Grid 5
{ 5, 3, 6, 4 }, //Grid 6
{ 6, 3, 7, 4 }, //Grid 7
{ 6, 2, 7, 3 }, //Grid 8
{ 6, 1, 7, 2 }, //Grid 9
{ 6, 0, 7, 1 } //Grid 10
};
However i received the error the above error. I saw some questions on SO which had the same issue, however I dont think they were dealing with SystemC. Any easy workaround for this in SystemC since im trying to initialize inside my SC_MODULE header/constructor?
Edit: I had a typo in my array initialization. Still get the same error.
2dArray[m][n] means m rows n columns so you can keep n values in each row but in your code you defined matrix which had 3 columns but still you are assigning 4 values.
You can use a loop for filling the array:
#include <iostream>
#include <stdlib>
int main()
{
srand(time(null));
int map[10][4];
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 4; j++)
{
map[i][j] = rand(); // you can write smth like rand() % 5 to make a limit of the values
}
}
return 0;
}
Suppose I have a matrix and a vector given by. How can I perform a search algorithm like binary search to return the index?
Example:
const int V_SIZE = 10,H_SIZE = 7;
int a1[V_SIZE][H_SIZE] = {
{1,2,0,0,0,0,0},
{1,3,0,0,0,0,0},
{2,2,4,0,0,0,0},
{2,2,6,0,0,0,0},
{3,2,4,7,0,0,0},
{4,1,3,5,9,0,0},
{4,1,4,6,8,0,0},
{4,2,3,4,7,0,0},
{5,2,3,5,7,8,0},
{6,1,3,4,5,7,10}
}; // sorted
int a2 [H_SIZE] = {4,1,3,5,9,0,0};
Perform a search for the vector a2 in the matrix a1 and the return value is 6
Thank a lot
You could use a 2D std::array in combination with std::lower_bound:
const int V_SIZE = 10,H_SIZE = 7;
std::array<std::array<int, H_SIZE>, V_SIZE> a1 {
{{{1,2,0,0,0,0,0}},
{{1,3,0,0,0,0,0}},
{{2,2,4,0,0,0,0}},
{{2,2,6,0,0,0,0}},
{{3,2,4,7,0,0,0}},
{{4,1,3,5,9,0,0}},
{{4,1,4,6,8,0,0}},
{{4,2,3,4,7,0,0}},
{{5,2,3,5,7,8,0}},
{{6,1,3,4,5,7,10}}
}}; // sorted
std::array<int, H_SIZE> a2 {{4,1,3,5,9,0,0}};
int idx = std::lower_bound(std::begin(a1), std::end(a1), a2) - std::begin(a1);
LIVE DEMO
If the matrix is sorted on the first number, you could use binary search to find an approximate index. You then have to go back until you find the first row starting with the same number as in the vector, as well as forward to find the last row starting with the same number. Then you loop over the vector, searching for a match for the second, third, etc. number in the range of rows you have.
What about something like this using std::array?
template <int HSIZE>
bool operator<(const std::array<int, HSIZE> &lhs, const std::array<int, HSIZE> &rhs)
{
for (int i = 0; i < HSIZE; i++)
if (lhs[i] != rhs[i])
return lhs[i] < rhs[i];
return false;
}
std::array<int, 7> a1[] =
{
{ 1, 2, 0, 0, 0, 0, 0 },
{ 1, 3, 0, 0, 0, 0, 0 },
{ 2, 2, 4, 0, 0, 0, 0 },
{ 2, 2, 6, 0, 0, 0, 0 },
{ 3, 2, 4, 7, 0, 0, 0 },
{ 4, 1, 3, 5, 9, 0, 0 },
{ 4, 1, 4, 6, 8, 0, 0 },
{ 4, 2, 3, 4, 7, 0, 0 },
{ 5, 2, 3, 5, 7, 8, 0 },
{ 6, 1, 3, 4, 5, 7, 10 }
};
void search(void)
{
std::array<int, 7> a2 = { 4, 1, 3, 5, 9, 0, 0 };
std::array<int, 7> *a1_end = a1 + sizeof(a1) / sizeof(std::array<int, 7>);
std::array<int, 7> *it = std::lower_bound(a1, a1_end, a2);
}