I have a 2D Matrix M[N][N] that I need to rotate counter-clockwise by 90 degrees. I have seen many answers for clockwise rotation but I cannot find counter-clockwise. How similar are the two operations?
If you reverse the order of each individual row and then taken rows in opposite order from a clockwise rotation, you get a count-clockwise rotation.
A B C G D A A D G C F I
D E F -> Clockwise -> H E B -> Reverse -> B E H -> Opposite -> B E H
G H I I F C Rows C F I Ordering A D G
Matrix Counter
Clockwise
Usually it's easier (and more computationally efficient) to do a clockwise rotation rotation on the original matrix in reverse order if you already have a clockwise rotating algorithm available.
1 2 3 9 8 7 3 6 9
4 5 6 -> Reverse -> 6 5 4 -> Clockwise -> 2 5 8
7 8 9 Indices 3 2 1 1 4 7
Matrix Counter
Clockwise
You can also just take 3 clockwise rotations to get to a counter clockwise rotation.
Though in reality it's usually fairly easy to edit the clockwise algorithm to your purposes directly. So I'd only use the above options if you don't care about efficiency and don't want to work through the logic of changing the direction of rotation.
From row(max), decrementing, fill in the result rows(incrementing index) with the values of that column, one after the other (incrementing).
So in a 3 x 3, use (using r, c notation like Excel)
(3, 1), (3, 2), (3, 3),
(2, 1), (2, 2), (2, 3),
etc.
You can just take the transpose 3 times, if you are using a particular matrix library
OK. let us say N =2 to be simple:
1 2
3 4
counter-clockwise 90 degree means that it will become:
2 4
1 3
We have the following rules:
1 last column from top to bottom of original matrix becomes
first row of rotated matrix from left to right
2 first column of original matrix becomes last row of rotated matrix
3 same rules apply to other columns of original matrix
You can easily code this out.
Another way to do is to first do a transpose on the matrix then reverse the order of all rows.
public static void main(String[] args) {
int[][] matrix = createAMatrix(3,3);
List<Stack<Integer>> tiltedMatrix = tiltMatrixBy90Now(matrix, 3);
int[][] newMatrix = new int[3][3];
for(int i = 0; i < 3; i ++) {
for(int j = 0; j < 3; j ++) {
newMatrix[i][j] = tiltedMatrix.get(j).pop();
}
}
//print new matrix
for(int i = 0; i < 3; i ++) {
for(int j = 0; j < 3; j ++) {
System.out.print(newMatrix[i][j]+" ");
}
System.out.println();
}
}
private static List<Stack<Integer>> tiltMatrixBy90Now(int[][] matrix , long order) {
List<Stack<Integer>> stackList = new ArrayList<>();
//filling the stack
for(int i = 0; i< order ; i++) {
stackList.add(new Stack<Integer>());
}
for(int i = 0; i < order; i ++) {
for(int j = 0; j < order; j ++) {
stackList.get(i).push(matrix[i][j]);
}
}
return stackList;
}
private static int[][] createAMatrix(final int a, final int b){
int counter = 1;
int[][] matrix = new int[a][b];
Scanner scanner = new Scanner(System.in);
while(counter <= a*b) {
for(int i = 0; i < a; i ++) {
for(int j = 0; j < b; j ++) {
matrix[i][j] = scanner.nextInt();
counter++;
}
}
}
return matrix;
}
/*
Input matrix (3 by 3)
1 2 3
4 5 6
7 8 9
Output matrix (3 by 3):
3 6 9
2 5 8
1 4 7
Code walk through as text explanation
Create a matrix , in above code It is 3*3 matrix
Creating 3 stacks from each row of 3*3 matrix
Pop from each stack one by one in parallel and and re-creating a matrix.
Printing the new tilted matrix by 90 degree(Anticlockwise).
*/
Related
let say I have a total number
tN = 12
and a set of elements
elem = [1,2,3,4]
and a prob for each element to be taken
prob = [0.0, 0.5, 0.75, 0.25]
i need to get a random multiset of these elements, such as
the taken elements reflects the prob
the sum of each elem is tN
with the example above, here's some possible outcome:
3 3 2 4
2 3 2 3 2
3 4 2 3
2 2 3 3 2
3 2 3 2 2
at the moment, maxtN will be 64, and elements the one above (1,2,3,4).
is this a Knapsack problem? how would you easily resolve it? both "on the fly" or "pre-calculate" approch will be allowed (or at least, depends by the computation time). I'm doing it for a c++ app.
Mission: don't need to have exactly the % in the final seq. Just to give more possibility to an elements to be in the final seq due to its higher prob. In few words: in the example, i prefer get seq with more 3-2 rather than 4, and no 1.
Here's an attempt to select elements with its prob, on 10 takes:
Randomizer randomizer;
int tN = 12;
std::vector<int> elem = {2, 3, 4};
std::vector<float> prob = {0.5f, 0.75f, 0.25f};
float probSum = std::accumulate(begin(prob), end(prob), 0.0f, std::plus<float>());
std::vector<float> probScaled;
for (size_t i = 0; i < prob.size(); i++)
{
probScaled.push_back((i == 0 ? 0.0f : probScaled[i - 1]) + (prob[i] / probSum));
}
for (size_t r = 0; r < 10; r++)
{
float rnd = randomizer.getRandomValue();
int index = 0;
for (size_t i = 0; i < probScaled.size(); i++)
{
if (rnd < probScaled[i])
{
index = i;
break;
}
}
std::cout << elem[index] << std::endl;
}
which gives, for example, this choice:
3
3
2
2
4
2
2
4
3
3
Now i just need to build a multiset which sum up to tN. Any tips?
I am facing problem with a 2D matrix consist of 3 column and N rows. Now I wanted to sort the matrix in such a way that the smallest of the first row is the first element, and so on. The first element of the second row is the smallest number with the smallest value of the first row. and similar to 3rd row. For example,
A B C
5 2 6
6 5 8
2 9 4
4 5 8
2 3 5
2 9 2
so the sorted matrix will be
A B C
2 3 5
2 9 2
2 9 4
4 5 8
5 2 6
6 5 8
Also, it will store the index of them such that
A_i B_i C_i
5 5 5
6 6 6
3 3 3
and so on...
I implemented this using C++ which is not computationally efficient and takes so much time for a very big matrix. How I can Implement this a computationally efficient way and fast?
My current C++ code for the same is as follow
for(int tii=0; tii<f_sizee; tii++){
track_index(tii)=tii+1;
}
for(int chkhk=0;chkhk<f_sizee;chkhk++){
if(check_index(chkhk)==1){
for(int chkhk1=chkhk+1;chkhk1<f_sizee;chkhk1++){
if((Va_mat(chkhk,0)==Va_mat(chkhk1,0))&&(Va_mat(chkhk,1)==Va_mat(chkhk1,1))&&(Va_mat(chkhk,2)==Va_mat(chkhk1,2))){
check_index(chkhk1)=0;
track_index(chkhk1)=seed_ind;
}
else track_index(chkhk)=seed_ind;
}
seed_ind=seed_ind+1;
}
}
int new_dim=sum(check_index);
int new_count=0;
mat unsort_vmat=zeros(new_dim,Va_mat.n_cols);
for(int iij=0; iij<f_sizee; iij++){
if(check_index(iij)==1){
unsort_vmat.row(new_count)=Va_mat.row(iij);
new_count++;
}
}
mat sort_vmat=zeros(new_dim,Va_mat.n_cols);
uvec indices = stable_sort_index(unsort_vmat.col(0));
int contrrS=0;
for(int sort_f=0; sort_f < new_dim; sort_f++){
for(uword sort_f2=0; sort_f2 < Va_mat.n_cols; sort_f2++){
contrrS=indices(sort_f);
sort_vmat(sort_f,sort_f2)=unsort_vmat(contrrS,sort_f2);
}
}
mat sort_vmat2 = zeros(new_dim,Va_mat.n_cols);
sort_vmat2 = sort_vmat ;
double element_tmp=0;
for(int iitr=0; iitr < new_dim; iitr++){
for(int iitk=iitr; iitk < new_dim; iitk++){
if(sort_vmat(iitk,0)==sort_vmat(iitr,0)){
if(sort_vmat(iitk,1)>sort_vmat(iitr,1)){///if error, delete this brace
element_tmp=sort_vmat(iitr,1);
sort_vmat(iitr,1)=sort_vmat(iitk,1);
sort_vmat(iitk,1)=element_tmp;
}
}
}
}
vec new_ind=zeros(f_sizee);
int start_ind=0;
for(int new_index=0; new_index<f_sizee; new_index++){
new_ind(new_index)=start_ind;
start_ind++;
}
int itr_count=0;
for(uword itr1=0; itr1<Va_mat.n_rows; itr1++){
for(int itr2=0; itr2<new_dim; itr2++){
if((Va_mat(itr1,0)==sort_vmat2(itr2,0))&&(Va_mat(itr1,1)==sort_vmat2(itr2,1))&&(Va_mat(itr1,2)==sort_vmat2(itr2,2))){
new_ind(itr_count)=itr2+1;
itr_count++;
}
}
}
int funda=0;
for(unsigned int Faa=0; Faa<Fa_mat.n_rows; Faa++){
for(unsigned int Fab=0; Fab<Fa_mat.n_cols; Fab++){
Fa_mat(Faa, Fab)=new_ind(funda);
funda++;
}
}
I want to rotate just the outer ring of a matrix clockwise.
Where n=number of steps to be rotate clockwise.
Suppose if I have a 4x5 matrix.
1 2 3 4 5
6 7 8 9 0
5 4 2 5 7
8 2 7 9 3
Now if n=1 the output should be :-
6 1 2 3 4
5 7 8 9 5
8 4 2 5 0
2 7 9 3 7
I have tried the logic of :
int temp = im[i][j];
im[i][j] = im[n-1-j][i];
im[n-1-j][i] = im[n-1-i][n-1-j];
im[n-1-i][n-1-j] = im[j][n-1-i];
im[j][n-1-i] = temp;
But I know this logic is completely wrong as it is moving the whole matrix.
You can do it like this:
Map and copy the border to a flat array
Apply std::rotate
Copy rotated array back into the border
Here is a sample implementation:
void rotate_border(int m[R][C], int n) {
vector<int> tmp(2*(R+C-2), -1);
for (size_t c = 0 ; c != C ; c++) {
tmp[c] = m[0][c];
tmp[c+C+R-2] = m[R-1][C-c-1];
}
for (size_t r = 1 ; r != R-1 ; r++) {
tmp[C+r-1] = m[r][C-1];
tmp[2*C+R-3+r] = m[R-r-1][0];
}
std::rotate(tmp.begin(), std::next(tmp.begin(), n), tmp.end());
for (size_t c = 0 ; c != C ; c++) {
m[0][c] = tmp[c];
m[R-1][C-c-1] = tmp[c+C+R-2];
}
for (size_t r = 1 ; r != R-1 ; r++) {
m[r][C-1] = tmp[C+r-1];
m[R-r-1][0] = tmp[2*C+R-3+r];
}
}
Demo.
Positive numbers rotate border counterclockwise. For clockwise rotation subtract the number from the size of the border. For example, 4✕5 matrix has the border of size 14, i.e. 5+(4-2)+5+(4-2). Hence, rotating by 1 clockwise requires rotating by 14-1.
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.
How would look the code that can transform an upper triangular matrix into a full matrix.
The matrix is in a vector, not in a bidimensional array...
so the array
[ 1 2 3 4
0 5 6 7
0 0 8 9
0 0 0 10 ]
would become an array like:
[ 1 2 3 4
2 5 6 7
3 6 8 9
4 7 9 10 ]
could you provide some ideas, I was thinking in applying a kind of module or something...
There is one restriction, I am not using bidimensional arrays
I am usng a vector, so is a unidimensional array
First, you must understand the fundemtnal nature of a reflected matrix. For any i, j, the following assertion is true:
m[i][j] ≡ m[j][i]
So, you need some algorithm to make that true. May I suggest:
for(int i = 0; i < HEIGHT; ++i)
for(int j = 0; j < i; ++j)
m[i][j] = m[j][i];
Note the condition of the 2nd loop. By ensuring that j is always less than i, we restrict our activity to the bottom-left triangle.
Next, you must understand how you have implemented a two-dimensional matrix in a one-dimensional array. It appears that you have established the identity:
m[i][j] ≡ v[i*WIDTH+j]
Substituting, we have:
for(int i = 0; i < HEIGHT; ++i)
for(int j = 0; j < i; ++j)
v[i*WIDTH+j] = v[j*WIDTH+i];