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
Suppose I have a following 2D matrix in the following format. First line indicates the dimension and the rest other lines contains the elements. In this case it's a 6*6 Matrix:
6
1 2 3 4 2 3
3 3 4 5 2 1
4 3 3 1 2 3
5 4 3 6 2 1
3 2 4 3 4 3
2 3 4 1 5 6
Normally we can store the matrix in a vector using this:
typedef std::vector<int32_t> vec_1d;
typedef std::vector<vec_1d> vec_2d;
vec_2d array{
{ 1, 2, 3, 4, 2, 3 }
, { 3, 3, 4, 5, 2, 1 }
, { 4, 3, 3, 1, 2, 3 }
, { 5, 4, 3, 6, 2, 1 }
, { 3, 2, 4, 3, 4, 3 }
, { 2, 3, 4, 1, 5, 6 }
};
But if I want to take this array in the format I have shown above from a text file into a 2d vector like the above one, how will I do this in c++ ?
This should work:
#include "fstream"
#include "vector"
using namespace std;
int main()
{
ifstream fin("file.txt");
int n;
fin >> n;
vector < vector <int> > matrix (n, vector <int>(n));
// or vec_2d matrix (n, vec_1d(n)); with your typedefs
for (auto &i: matrix)
for (auto &j: i)
fin >> j;
}
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);
}
I'm trying to brute force the following problem
https://projecteuler.net/problem=18
I can't think of a solution and my head is stucked, I don't know how to choose each path. what I did is the following
vector<vector<int> > triangle =
{
{ 3 },
{ 7, 4 },
{ 2, 4, 6 },
{ 8, 5, 9, 3 }
};
int maxSum = 0;
for (int i = 0; i < triangle.size(); i++)
{
for (int j = 0; j < triangle[i].size(); j++)
{
}
}
3
7 4
2 4 6
8 5 9 3
When brute-forcing, you have to sum the numbers of following branches and find the maximum:
3, 7, 2, 8
3, 7, 2, 5
3, 7, 4, 5
...
3, 4, 6, 3
How do you generate such sequences?
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! :)