Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by 90 degrees. Can you do this in place?
A:
public class Main {
public static void main(String[] args) {
int imSize = 6;
int[][] image = new int[imSize][imSize];
// Initialize image
Tool.randomInitializeArray(image);
Tool.printArray(image);
rotateImage90(image);
Tool.printArray(image);
}
public static void rotateImage90(int[][] im) {
// rotate the matrix in place, clock wise direction of 90 degree
int numRow = im.length;
int numCol = im[1].length;
// check they are square matrix
if (numRow != numCol) {
System.out.println("not square matrix");
}
if (numRow == 0) { // actually, this could be ignored.
System.out.println("no elements");
}
int imSize = numRow;
if (imSize % 2 == 1) {
// if imSize is odd number, rotate from the most inner circle ( of
// size 1*1)
int centerIndex = (int) (numRow / 2) + 1; // in math, this is the
// center point.
centerIndex = centerIndex - 1; // because java starts array index
// from zero, we need minus 1
int radius = (int) (numRow / 2);
for (int d = 1; d <= radius; d++) {
// there are four lines per circle. we rotate them
// one-by-one
int lineLength = 2 * d;
int[] tmpLine = new int[lineLength];
// save the line above to tempArray
for (int i = -d + 1; i <= d; i++)
// ignore the left most vertex
tmpLine[i - (-d + 1)] = im[centerIndex - d][centerIndex + i];
// copy left to above
for (int i = -d + 1; i <= d; i++)
im[centerIndex - d][centerIndex + i] = im[centerIndex - i][centerIndex
- d];
// copy below to left
for (int i = -d + 1; i <= d; i++)
im[centerIndex - i][centerIndex - d] = im[centerIndex + d][centerIndex
- i];
// copy right to below
for (int i = -d + 1; i <= d; i++)
im[centerIndex + d][centerIndex - i] = im[centerIndex + i][centerIndex
+ d];
// copy original above(now in tmpLine) to right
for (int i = -d + 1; i <= d; i++)
im[centerIndex + i][centerIndex + d] = tmpLine[i - (-d + 1)];
}
} else { // imSize is even number, i.e. , imSize == 2, 4 , 6, 8....
int indexLeftTop = (int) (imSize / 2) - 1;
int indexRightBottom = (int) (imSize / 2);
int radius = (int) (imSize / 2);
// because by considering
System.out.println("we are working on the array, sized == "
+ imSize);
for (int d = 1; d <= radius; d++) { // for each layer,with distance
// to center is d
int lineLength = indexRightBottom - indexLeftTop;
int tmpLine[] = new int[lineLength];
// save the above circle into the tmpLine ( do not include the
// topLeft corner
for (int i = 1; i <= lineLength; i++) {
tmpLine[i - 1] = im[indexLeftTop][indexLeftTop + i];
}
// transfer the left into above
for (int i = 1; i <= lineLength; i++) {
im[indexLeftTop][indexLeftTop + i] = im[indexRightBottom
- i][indexLeftTop];
}
// transfer the bottom into left
for (int i = 1; i <= lineLength; i++) {
im[indexRightBottom - i][indexLeftTop] = im[indexRightBottom][indexRightBottom
- i];
}
// transfer the right into the bottom
for (int i = 1; i <= lineLength; i++) {
im[indexRightBottom][indexRightBottom - i] = im[indexLeftTop
+ i][indexRightBottom];
}
// transfer the saved,original above line into the right
for (int i = 1; i <= lineLength; i++) {
im[indexLeftTop + i][indexRightBottom] = tmpLine[i - 1];
}
indexLeftTop--;
indexRightBottom++;
}// end of the for, for each layer, from inner most to the outer
// most
} // end of else, for the case that the length is even number
} // end of function rotateImage90
}
Mistakes:0: FUCK!!!!!!!!!!!
因为在rotate完毕,要打印数组的时候,是直接从上面copy的两个for loop,其中,就包含了一行 image[i][j] 的初始化代码。。我日阿
以后再copy代码的时候,一定要注意,先看看代码里都是什么。(即使是自己写 的)
1: 遇到数组溢出。 问题出在
int centerIndex = (int)(numRow/2) + 1;
int radius = (int)(numRow/2)+1; //这里,的radius是从上面一行copy下来的。
而应该自己写, 就不会加上这个 1 了。----------哎,人生阿
2: 遇到数组问题, 毛病出在。
自己作运算的时候, 都是按照数学里的start from 1, 来计算,安排的。
可是,java中是start from 0. ------------> 刚开始的时候,还记得,但是,直接写index的时候,就忘了。
3:for odd number, for each line, to copy and rotate into another line, 应该记住,一条边,随说是包括两边顶点。 但rotate的时候,只需要一个顶点就够了
for(int i = -d; i<=d;i++) ------------------------这是错误的
for(int i = -d; i<d;i++) ------------------------这是正确的。
4:对于数组
a b c
d e f
g h i
如果按照上面的rotate算法,[a; d] 应该是 取代[ b c ] 的位置。
而不是,[ d ; g] 取代 [a b]的位置。
因此:我的初始代码中
int imSize = numRow;
// if imSize is odd number, rotate from the most inner circle ( of size 1*1)
int centerIndex = (int)(numRow/2) + 1; // mathetically, this is the center point.
centerIndex = centerIndex -1; // because java starts array index from zero, we need minus 1
int radius = (int)(numRow/2);
for (int d = 1; d <= radius; d++){
// there are four lines for each circle. we just rotate them one-by-one
int lineLength = 1+2*d;
int[] tmpLine = new int[lineLength];
// save the line above to tempArray
for(int i = -d; i
是错误的, 是假设了[ d ; g] 取代 [a b]的位置。
5: 对于,矩形边是偶数的时候 , 在rotate完了每一圈之后, 忘了update indexLeftTop 和indexRightBottom的值了。
No comments:
Post a Comment