Matrix with 1d vector - c++

I represent a n*m matrix like chessboard.
1 0 2 0
0 3 0 4
5 0 6 0
0 7 0 8
I don't need to store the zeros in my 1d vector.
vector v = {1, 2, 3, 4.. etc}
I ask the user for a row and column number.
How can i return with i. row j. column element?
if (i+j) % 2 != 0
I return with 0, but i don't know what i need to do when
(i+j) % 2 == 0
Can you help me? (sorry for my bad English)

With regular matrices stored as 1D-vector, coordinate to index would be:
(i + j * width) (or i * height + j depending on convention).
with half case to 0, you just have to divide by 2:
if ((i + j) % 2 != 0) return 0;
else return data[(i + j * width) / 2];

Related

How to check if exists array[i][j] in c++?

I have two dimensional array of chars, where all numbers, excluding one * (as given in picture (two examples)
My task is to sum up all neighbour integers ( in example 1, neighbours of * are 4,2,5,8 and sum is 4+2+5+8=19)
But in example 2, * doesn't have top neighbour.
My initial code was like:
arr[i-1][j] + arr[i+1][j] + arr[i][j-1] + arr[i][j+1]
But then I understood that in case like a[0][-1] doesn't exist. So can you help me to to solve my problem
You need to explicitly check each one. The following should work:
bool inRange(int i, int j) {
const auto n = 4; // you need to set this somewhere, or pass it in
return (i >= 0) && (i < n) && (j >= 0) && (j < n);
}
auto sum = (inRange(i-1, j) ? arr[i-1][j] : 0)
+ (inRange(i+1, j) ? arr[i+1][j] : 0)
+ (inRange(i, j-1) ? arr[i][j-1] : 0)
+ (inRange(i, j+1) ? arr[i][j+1] : 0);
You can probably write this a little cleaner, but you need to check not only for the -1, but also for when you go over 3.
There can be multiple solutions to this problem, but if you want to avoid checking bound each time you can extend the matrix dimension by 1 than needed. That means if you have an array:
1 * 4 7
8 9 2 3
5 1 2 4
4 3 6 5
Implement it as:
0 0 0 0 0 0
0 1 * 4 7 0
0 8 9 2 3 0
0 5 1 2 4 0
0 4 3 6 5 0
0 0 0 0 0 0
Doing this won't even affect your sum at the end.

find a selection of elements adjacent sum = 10

Description:
Given matrix [x] [y], with x- rows and y- number of columns . Filled random numbers from 0 to 5 inclusive .
Description of finding a solution : the solution is considered to be a set of matrix elements that are adjacent to each other ( diagonal neighborhood is not taken into account ) and the sum of the number are 10. Each element of the matrix can be used 1 time for a decision . The solution may have any number of digits. The decision must end any number other than zero .
Example:
given
0 1 2 3 4 5
1 2 3 4 5 0
2 3 4 5 1 2
Solution 1 : (1 - 2 - 3 - 4)
0 **1** 2 3 4 5
1 **2** 3 4 5 0
2 **3** **4** 5 1 2
i tried to do smth like this, but it is wrong, i dont know when i must stop,
Solution it is a class which contains mair of indexes, pls help me.
void xxx(int colCount, int rowCount, int currentRow, int currentCol, int** matrix, int sum, Solution *solution, int solCount) {
sum += matrix[currentRow][currentCol];
matrix[currentRow][currentCol] = -1;
if(sum > 10){
sum - = matrix[currentRow][currentCol];
return;
} else if(sum == 10){
solution[solCount].additem(currentRow, currentCol);
return xxx(5,5,currentRow - 1, currentCol, matrix, sum, solution, solCount+1);
} else {
//UP
if( currentRow > 0 && matrix [currentRow - 1][currentCol] != -1){
xxx(5,5,currentRow - 1, currentCol, matrix, sum, solution,solCount);
}
//LEFT
if(currentCol > 0 && matrix [currentRow][currentCol-1] != -1){
xxx(5,5,currentRow, currentCol - 1, matrix, sum, solution,solCount);
}
//DOWN
if(currentRow + 1 < colCount && matrix[currentRow + 1][currentCol] != -1){
xxx(5,5,currentRow + 1, currentCol, matrix, sum, solution,solCount);
}
//RIGHT
if(currentCol + 1 < rowCount && matrix[currentRow][currentCol + 1] != -1){
xxx(5,5,currentRow, currentCol + 1, matrix, sum, solution,solCount);
}
}
}

Linear index upper triangular matrix

If I have the upper triangular portion of a matrix, offset above the diagonal, stored as a linear array, how can the (i,j) indices of a matrix element be extracted from the linear index of the array?
For example, the linear array [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 is storage for the matrix
0 a0 a1 a2 a3
0 0 a4 a5 a6
0 0 0 a7 a8
0 0 0 0 a9
0 0 0 0 0
And we want to know the (i,j) index in the array corresponding to an offset in the linear matrix, without recursion.
A suitable result, k2ij(int k, int n) -> (int, int) would satisfy, for example
k2ij(k=0, n=5) = (0, 1)
k2ij(k=1, n=5) = (0, 2)
k2ij(k=2, n=5) = (0, 3)
k2ij(k=3, n=5) = (0, 4)
k2ij(k=4, n=5) = (1, 2)
k2ij(k=5, n=5) = (1, 3)
[etc]
The equations going from linear index to (i,j) index are
i = n - 2 - floor(sqrt(-8*k + 4*n*(n-1)-7)/2.0 - 0.5)
j = k + i + 1 - n*(n-1)/2 + (n-i)*((n-i)-1)/2
The inverse operation, from (i,j) index to linear index is
k = (n*(n-1)/2) - (n-i)*((n-i)-1)/2 + j - i - 1
Verify in Python with:
from numpy import triu_indices, sqrt
n = 10
for k in range(n*(n-1)/2):
i = n - 2 - int(sqrt(-8*k + 4*n*(n-1)-7)/2.0 - 0.5)
j = k + i + 1 - n*(n-1)/2 + (n-i)*((n-i)-1)/2
assert np.triu_indices(n, k=1)[0][k] == i
assert np.triu_indices(n, k=1)[1][k] == j
for i in range(n):
for j in range(i+1, n):
k = (n*(n-1)/2) - (n-i)*((n-i)-1)/2 + j - i - 1
assert triu_indices(n, k=1)[0][k] == i
assert triu_indices(n, k=1)[1][k] == j
First, let's renumber a[k] in opposite order. We'll get:
0 a9 a8 a7 a6
0 0 a5 a4 a3
0 0 0 a2 a1
0 0 0 0 a0
0 0 0 0 0
Then k2ij(k, n) will become k2ij(n - k, n).
Now, the question is, how to calculate k2ij(k, n) in this new matrix. The sequence 0, 2, 5, 9 (indices of diagonal elements) corresponds to triangular numbers (after subtracting 1): a[n - i, n + 1 - i] = Ti - 1. Ti = i * (i + 1)/2, so if we know Ti, it's easy to solve this equation and get i (see formula in the linked wiki article, section "Triangular roots and tests for triangular numbers"). If k + 1 is not exactly a triangular number, the formula will still give you the useful result: after rounding it down, you'll get the highest value of i, for which Ti <= k, this value of i corresponds to the row index (counting from bottom), in which a[k] is located. To get the column (counting from right), you should simply calculate the value of Ti and subtract it: j = k + 1 - Ti. To be clear, these are not exacly i and j from your problem, you need to "flip" them.
I didn't write the exact formula, but I hope that you got the idea, and it will now be trivial to find it after performing some boring but simple calculations.
The following is an implimentation in matlab, which can be easily transferred to another language, like C++. Here, we suppose the matrix has size m*m, ind is the index in the linear array. The only thing different is that here, we count the lower triangular part of the matrix column by column, which is analogus to your case (counting the upper triangular part row by row).
function z= ind2lTra (ind, m)
rvLinear = (m*(m-1))/2-ind;
k = floor( (sqrt(1+8*rvLinear)-1)/2 );
j= rvLinear - k*(k+1)/2;
z=[m-j, m-(k+1)];
For the records, this is the same function, but with one-based indexing, and in Julia:
function iuppert(k::Integer,n::Integer)
i = n - 1 - floor(Int,sqrt(-8*k + 4*n*(n-1) + 1)/2 - 0.5)
j = k + i + ( (n-i+1)*(n-i) - n*(n-1) )÷2
return i, j
end
Here is a more efficient formulation for k:
k = (2 * n - 3 - i) * i / 2 + j - 1
In python 2:
def k2ij(k, n):
rows = 0
for t, cols in enumerate(xrange(n - 1, -1, -1)):
rows += cols
if k in xrange(rows):
return (t, n - (rows - k))
return None
In python, the most efficient way is:
array_size= 3
# make indices using k argument if you want above the diagonal
u, v = np.triu_indices(n=array_size,k=1)
# assuming linear indices above the diagonal i.e. 0 means (0,1) and not (0,0)
linear_indices = [0,1]
ijs = [(i,j) for (i,j) in zip(u[linear_indices], v[linear_indices])]
ijs
#[(0, 1), (0, 2)]

Partitioning arrays by index

I am fairly new to C++, and am struggling through a problem that seems to have a solid solution but I just can't seem to find it. I have a contiguous array of ints starting at zero:
int i[6] = { 0, 1, 2, 3, 4, 5 }; // this is actually from an iterator
I would like to partition the array into groups of three. The design is to have two methods, j and k, such that given an i they will return the other two elements from the same group of three. For example:
i j(i) k(i)
0 1 2
1 0 2
2 0 1
3 4 5
4 3 5
5 3 4
The solution seems to involve summing the i with its value mod three and either plus or minus one, but I can't quite seem to work out the logic.
This should work:
int d = i % 3;
int j = i - d + ( d == 0 );
int k = i - d + 2 - ( d == 2 );
or following statement for k could be more readable:
int k = i - d + ( d == 2 ? 1 : 2 );
This should do it:
int j(int i)
{
int div = i / 3;
if (i%3 != 0)
return 3*div;
else
return 3*div+1;
}
int k(int i)
{
int div = i / 3;
if (i%3 != 2)
return 3*div+2;
else
return 3*div+1;
}
Test.
If you want shorter functions:
int j(int i)
{
return i/3*3 + (i%3 ? 0 : 1);
}
int k(int i)
{
return i/3*3 + (i%3-2 ? 2 : 1);
}
Well, first, notice that
j(i) == j(3+i) == j(6+i) == j(9+i) == ...
k(i) == k(3+i) == k(6+i) == k(9+i) == ...
In other words, you only need to find a formula for
j(i), i = 0, 1, 2
k(i), i = 0, 1, 2
and then for the rest of the cases simply plug in i mod 3.
From there, you'll have trouble finding a simple formula because your "rotation" isn't standard. Instead of
i j(i) k(i)
0 1 2
1 2 0
2 0 1
for which the formula would have been
j(i) = (i + 1) % 3
k(i) = (i + 2) % 3
you have
i j(i) k(i)
0 1 2
1 0 1
2 0 2
for which the only formula I can think of at the moment is
j(i) = (i == 0 ? 1 : 0)
k(i) = (i == 1 ? 1 : 2)
If the values of your array (let's call it arr, not i in order to avoid confusion with the index i) do not coincide with their respective index, you have to perform a reverse lookup to figure out their index first. I propose using an std::map<int,size_t> or an std::unordered_map<int,size_t>.
That structure reflects the inverse of arr and you can extra the index for a particular value with its subscript operator or the at member function. From then, you can operate purely on the indices, and use modulo (%) to access the previous and the next element as suggested in the other answers.

Sum of submatrices of bigger matrix

I have a big matrix as input, and I have the size of a smaller matrix. I have to compute the sum of all possible smaller matrices which can be formed out of the bigger matrix.
Example.
Input matrix size: 4 × 4
Matrix:
1 2 3 4
5 6 7 8
9 9 0 0
0 0 9 9
Input smaller matrix size: 3 × 3 (not necessarily a square)
Smaller matrices possible:
1 2 3
5 6 7
9 9 0
5 6 7
9 9 0
0 0 9
2 3 4
6 7 8
9 0 0
6 7 8
9 0 0
0 9 9
Their sum, final output
14 18 22
29 22 15
18 18 18
I did this:
int** matrix_sum(int **M, int n, int r, int c)
{
int **res = new int*[r];
for(int i=0 ; i<r ; i++) {
res[i] = new int[c];
memset(res[i], 0, sizeof(int)*c);
}
for(int i=0 ; i<=n-r ; i++)
for(int j=0 ; j<=n-c ; j++)
for(int k=i ; k<i+r ; k++)
for(int l=j ; l<j+c ; l++)
res[k-i][l-j] += M[k][l];
return res;
}
I guess this is too slow, can anyone please suggest a faster way?
Your current algorithm is O((m - p) * (n - q) * p * q). The worst case is when p = m / 2 and q = n / 2.
The algorithm I'm going to describe will be O(m * n + p * q), which will be O(m * n) regardless of p and q.
The algorithm consists of 2 steps.
Let the input matrix A's size be m x n and the size of the window matrix being p x q.
First, you will create a precomputed matrix B of the same size as the input matrix. Each element of the precomputed matrix B contains the sum of all the elements in the sub-matrix, whose top-left element is at coordinate (1, 1) of the original matrix, and the bottom-right element is at the same coordinate as the element that we are computing.
B[i, j] = Sum[k = 1..i, l = 1..j]( A[k, l] ) for all 1 <= i <= m, 1 <= j <= n
This can be done in O(m * n), by using this relation to compute each element in O(1):
B[i, j] = B[i - 1, j] + Sum[k = 1..j-1]( A[i, k] ) + A[j] for all 2 <= i <= m, 1 <= j <= n
B[i - 1, j], which is everything of the sub-matrix we are computing except the current row, has been computed previously. You keep a prefix sum of the current row, so that you can use it to quickly compute the sum of the current row.
This is another way to compute B[i, j] in O(1), using the property of the 2D prefix sum:
B[i, j] = B[i - 1, j] + B[i, j - 1] - B[i - 1, j - 1] + A[j] for all 1 <= i <= m, 1 <= j <= n and invalid entry = 0
Then, the second step is to compute the result matrix S whose size is p x q. If you make some observation, S[i, j] is the sum of all elements in the matrix size (m - p + 1) * (n - q + 1), whose top-left coordinate is (i, j) and bottom-right is (i + m - p + 1, j + n - q + 1).
Using the precomputed matrix B, you can compute the sum of any sub-matrix in O(1). Apply this to compute the result matrix S:
SubMatrixSum(top-left = (x1, y1), bottom-right = (x2, y2))
= B[x2, y2] - B[x1 - 1, y2] - B[x2, y1 - 1] + B[x1 - 1, y1 - 1]
Therefore, the complexity of the second step will be O(p * q).
The final complexity is as mentioned above, O(m * n), since p <= m and q <= n.