一、题目
- 问题描述
回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。
输入格式
输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列。接下来m行每行n个整数,表示这个矩阵。
输出格式
输出只有一行,共mn个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。
样例输入
3 3
1 2 3
4 5 6
7 8 9
样例输出
1 4 7 8 9 6 3 2 5
样例输入
3 2
1 2
3 4
5 6
样例输出
1 3 5 6 4 2
二、代码与解析
1、完整代码
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
int m = input.nextInt(); //要输入的行数
int n = input.nextInt(); //要输入的列数
int arr[][] = new int[m][n]; //创建二维数组
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
arr[i][j] = input.nextInt(); //对二维数组输入数据
input.close();
int rightDowmRow = arr.length - 1; //定义矩阵最大行数
int rightDowmCol = arr[0].length - 1; //定矩阵最大列数
int leftTopRow = 0; //定矩阵最小行数
int leftTopCol = 0; //定矩阵最小列数
/*将矩阵逆时针全部输出*/
while (leftTopRow <= rightDowmRow && leftTopCol <= rightDowmCol) {
int Row = leftTopRow;
int Col = leftTopCol;
if(rightDowmCol-leftTopCol==0) { //如果矩阵只有一列
while (Row <= rightDowmRow) //把所有的行全部输出,直到结束
System.out.print(arr[Row++][Col] + " ");//每输出一个元素,下移一行
}
else if(rightDowmRow-leftTopRow==0) { //如果只有一列
while (Col <= rightDowmCol) //把所有的列全部输出,直到结束
System.out.print(arr[Row][Col++] + " ");//输出一个元素,右移一列
}
else { //如果不符合以上两种情况,执行以下代码
while (Row <= rightDowmRow) //因为为你循环取数,所以先向下
System.out.print(arr[Row++][Col] + " ");//没输出一个元素,就向下移一位
Row = rightDowmRow; //由于退循环时,Row已经超过最大的数,所以将他恢复为最大的数
Col++; //使列数往右移
while (Col <= rightDowmCol)
System.out.print(arr[Row][Col++] + " ");
Col = rightDowmCol;
Row--;
while (Row >= leftTopRow)
System.out.print(arr[Row--][Col] + " ");
Row = leftTopRow;
Col--;
while (Col > leftTopCol)
System.out.print(arr[Row][Col--] + " ");
}
/*没执行完一环,将所有的最大最小标志数往里缩小*/
rightDowmRow--;
rightDowmCol--;
leftTopRow++;
leftTopCol++;
}
}
}
2、部分代码
if(rightDowmCol-leftTopCol==0) { //如果矩阵只有一列
while (Row <= rightDowmRow) //把所有的行全部输出,直到结束
System.out.print(arr[Row++][Col] + " ");//每输出一个元素,下移一行
}
else if(rightDowmRow-leftTopRow==0) { //如果只有一列
while (Col <= rightDowmCol) //把所有的列全部输出,直到结束
System.out.print(arr[Row][Col++] + " ");//输出一个元素,右移一列
}
- 这两种只适合只有单行和单列的情况,我需要用一个while循环某一列的内容或某一行的内容全部输出即可,用Row或Col作为当前位置的标志,在当前位置让然小于或等最大的元素下标时,就输出打印,随后进行自加操作。
else { //如果不符合以上两种情况,执行以下代码
while (Row <= rightDowmRow) //因为为你循环取数,所以先向下
System.out.print(arr[Row++][Col] + " ");//没输出一个元素,就向下移一位
Row = rightDowmRow; //由于退循环时,Row已经超过最大的数,所以将他恢复为最大的数
Col++; //使列数往右移
while (Col <= rightDowmCol)
System.out.print(arr[Row][Col++] + " ");
Col = rightDowmCol;
Row--;
while (Row >= leftTopRow)
System.out.print(arr[Row--][Col] + " ");
Row = leftTopRow;
Col--;
while (Col > leftTopCol)
System.out.print(arr[Row][Col--] + " ");
}
/*没执行完一环,将所有的最大最小标志数往里缩小*/
rightDowmRow--;
rightDowmCol--;
leftTopRow++;
leftTopCol++;
}
- 只是用这部分的代码只能对行和列相等的的数组或方阵进行回环输出,对于非方阵或者行列不相等的数组只能输出错误的结果;这种方式的思想是先把最外层的输出,让后一层一层往里缩,直到全部输出。
三、测试结果
四、总结与心得
- 遇到二维数组的遍历且涉及方向的一般都需要有四个循环,普通情况下最少也是需要两个循环,才能进程序的编写,本题给出的是逆循环遍历输出,而如果是顺时时针输出,则只需要改变四个while循环的顺序即可,先往右再往下,再往左,最后往上,即可实现顺时针循环输出。