Navigating an Array with Column Boundaries - c++

Let's say there is a square 2 dimensional array of N x N, represented as a one dimension array. Let the array be 5x5, like below, and the values in the array are not significant.
std::vector< int > array {
0, 1, 2, 3, 4,
5, 6, 7, 8, 9,
0, 1, 2, 3, 4,
5, 6, 7, 8, 9,
0, 1, 2, 3, 4
};
If we say that there are 5 rows and 5 columns in this array, how can one detect if they are on the edge of a row? For instance, if you are on the index of where 9 is on the 4th row, how can you know that you can go left without changing rows, but going right will advance to the next row? How can one access a cell's neighbors with respect to edges? The index of where 9 is on the 4th row does not have a right neighbor.
The only way I can think of how to do this would be the current index, in which case is
int index = row * num_cols + col
and perhaps use modulus (index % 5 == 0) to determine if on edge. But that does not determine if we can go left or right.

Your formula
int index = row * num_cols + col;
Going up or down is equivalent to adding / subtracting num_cols.
is correct. The reverse of it is
int row = index / num_cols;
int col = index % num_cols;
You know you're on the left edge when (index % num_cols) == 0.
You know you're on the right edge when (index % num_cols) == num_cols-1.

You can use
int row = index / N;
int col = index % N;
to get the row and column indices. For example, the 9th entry has row index 9/5=1 and column index 9%5=4.
Having computed the (row, col) coordinate, you can determine if it has the left or right neighbors. When col == 0, you don't have a left neighbor; when col == N-1, you don't have a right neighbor.

Related

how to print the max sequence of a given vector (possible values 1 and 0) with the property that are different and the number of the max sequence c++

Let's say I have a vector v with random 1 and 0.
std::vector<int> v = {1,0,1,0,0,1,0,1};
I want to find out the max sequence with the property v[i] != v[i-1]. Basically the numbers need to be different. In this example the max sequence is 4 (1, 0, 1, 0) from position v[0] to v[3]. There is also (0,1,0,1) from position v[4] to v[7]. There are 2 max sequences so the final output should look like this:
4 2
Where 4 is the max sequence and 2 the numbers of max sequences.
Let's take another example:
std::vector<int> v2 = {1,0,1,1,1,0,1,0,1,0};
The output here should be:
6 1
The max sequence starts from v[4] to v[9]. There is only one max sequence so it will print 1 this time.
I tried to solve this using a for loop:
n - number of integers in the vector
k - number of different integers in vector
maxk - the max sequence
many - how many max sequence are
for(int i{1}; i < n; i++) {
if(v[i] != v[i-1]) {
k++;
if(k > maxk) {
maxk = k;
}
}
else {
if(k == maxk) {
many++;
}
else {
many = 1;
}
k = 1;
}
}
But if you give it a vector like {1, 0, 0} it will not work. Can someone give me a tip of how this problem can be solved? Sorry for my bad english
First, sequence isn't the right word. A sequence can jump past elements. You mean a subarray.
Second, you talk about arrays with 0 and 1 in them, then give an example with 2. Do you want to not count subarrays with 2? Or count them? In other words if the input is [1, 2, 2] are you expecting an answer of 1 1 or 2 1?'.
That said, just make an array of where the best current subarray begins. For your first example that array would look like this:
1, 0, 1, 0, 0, 1, 0, 1
0, 0, 0, 0, 4, 4, 4, 4
And then a linear scan finds that you have a group of 4 starting at index 0, and another group of 4 starting at index 4.
For your next example,
1, 0, 1, 1, 1, 0, 1, 0, 1, 0
0, 0, 0, 3, 4, 4, 4, 4, 4, 4
And you have a group of 3 starting at index 0, 1 starting at 3, and 6 starting at 4. So we've found the 1 group of 6.
For your last example, what you'd get would depend on the answer you want.
I'll leave coding this to you.

How to check if 2d vector element is in a certain index range

I want to check whether or not a certain element of a 2d vector is within an index range. For example, I have the following vector:
{1, 2, 3, 4, 5,
6, 7, 8, 9, 10,
11, 12, 13, 14, 15}
How might I check whether or not the element number 7 (or [1][1]) is within the index range of 0 to 2 on the x axis and 0 to 1 on the y axis? Or in other words a 3x2 partition of the vector from the top left corner.
For the y axis you can do it like this:
index/width < yLimit
For the x axis, it would be like this:
index%width < xLimit
where width is the width of the 2d array, and xLimit and yLimit are the maximum you want your x-axis number and your y-axis number to be respectively.
Note that this number should be greater than or equal to 0 anyway, since negative indices are not a thing in C++.
Also note that I use < here, but I recon if you want to include 1 or 2 in your possible indices, you should use <= instead.
If you want them together, a logical and will do nicely:
index/width < yLimit && index%width < xLimit

Eigen matrix rowwise addition

I have an Nx3 Eigen matrix representing a bunch of locations of vertices in 3d space.
I'm trying to add a 1x3 matrix to each row in the Nx3 to move every point a given direction and distance.
#include <Eigen/Dense>
int N = 20; //for example
MatrixXf N3(N, 3);
N3.fill(2);
MatrixXf origin(1, 3);
origin << 1, 2, 3;
Now I want to add origin to each row in N3 so N3 becomes 3, 4, 5 in each row. (The values in N3 are all different 3d vertex locations in the real code.)
3, 4, 5
3, 4, 5
3, 4, 5 etc...
you may just write
N3 += origin.replicate(N,1);
note that no temporary matrix is created, replicate() returns an expression.
Try this (untested)
for (int i = 0 ; i < 3 ; i++)
N3.block(i, 0, 1, 3) = N3.block(i, 0, 1, 3) + origin
I do not remember if += is supported
MatrixXf result = N3 + MatrixXf::Constant(1, N, 1) * origin;
Should be simple as that.

How can I order an array with duplicate values?

I want to order an array of stuffs that may have duplicates. For example:
int values[5] = {4, 5, 2, 5, -1};
int expected[5] = {1, 2, 0, 2, -1};
Here 2 is the smallest element so its order is 0. 4 is the 2nd smallest so its order is 1. 5 is the 3rd smallest and I want both of them have the order 2. I want to skip over certain elements (-1 in the above example) so these elements will have order -1.
How do I do this in C++ or describe an algorithm ?
Thanks
Just sort the array, then assign each element its rank:
vector<int> v(values, values + 5);
v.push_back(-1);
sort(begin(v), end(v));
v.resize(unique(begin(v), end(v)) - begin(v));
for (int i = 0; i < 5; ++i)
expected[i] = lower_bound(begin(v), end(v), values[i]) - begin(v) - 1;
This assumes that all the elements are non-negative or -1. If there are negative elements that are smaller than -1, you need to special case the -1.

N-Dimensional Grid Vertices Calculation

QUESTION: Given a cell index (red) compute the array index (black) that surround the cell index.
bool CalculateCellVerticesFromIndex(size_t index, size_t* vertices)
{
size_t gridSize[2] = {6, 5};
return true; // if the index was valid
return false; // if the index was invalid
}
Calculate the vertices that surround a cell in a N-dimensional grid of known size (m X n X ... ).
Example diagram:
Say int vertices[4] = {0, 0, 0, 0}
In the above diagram, CalculateCellVerticesFromIndex(12, vertices); should fill vertices up with {14, 15, 20, 21};
Width = 6
Row = Index div (Width - 1)
if Row > 5 - 2 then OutOfGrid
Column = Index mod (Width - 1)
LeftBottom = Row * Width + Column
LeftTop = LeftBottom + Width
RightBottom and RightTop - elaborate