列印如下圖案
16 15 14 13
5 4 3 12
6 1 2 11
7 8 9 10
要求可動態更改任意行數和列數
以下提供兩種方法,個人覺得方法二的思路清晰些,因為使用遞迴每次填充一圈資料,直到填充完所有圈資料.還有,填充一圈資料時,沒必要一個一個數字迴圈填寫,其實只要迴圈首行的資料,就能計算出末行的資料,只要迴圈首列的資料,就能計算出末列的資料,這樣就能節省一半的迴圈操作.
方法一:
/**
*
該程式可以更改列印幾行幾列
原理:通過定位行號與列號,逐個逐個從大往小賦值.
@author zhangle
*/
public static void main(String[] args) {
int row=4;//幾行
int col=4;//幾列
int[][] m=new int[row][col];//二維數組,用於存放結果
int n=col*row;//該矩陣中的最大值
int i=0;//行號
int j=1;//列號
int t_col=col;//列迴圈變數
int t_row=row;//行迴圈變數
while(true) {
//賦值某行
for(int k=0;k<t_col;k++) {
j+=-1;
m[Math.abs(i)][Math.abs(j)]=n--;
}
if(n==0) break;//如果值已賦完,則退出
t_col--;//列迴圈--
t_row--;//行迴圈--
//賦值某列
for(int k=0;k<t_row;k++) {
i+=-1;
m[Math.abs(i)][Math.abs(j)]=n--;
}
if(n==0) break;//如果值已賦完,則退出
j=-j;
i=-i;
}
print(m);
}
/**
* 列印二維數組
* @param a
*/
static void print(int[][] a) {
for(int i=0;i<a.length;i++) {
for(int j=0;j<a[i].length;j++) {
System.out.print(" "+a[i][j]);
}
System.out.println();
}
}
方法二:
原理:先填寫最外一圈的資料,如果還有內圈資料,則遞迴調用本身繼續填寫內圈資料,直到填寫完畢
public class Round {
public static void main(String[] args) {
int row=10; //幾行
int col=10; //幾列
int[][] a=new int[row][col];
fill(a,row,col,0,0);
print(a);
}
/**
* 填寫最外一圈的資料,如果還有內圈資料,則遞迴調用本身繼續填寫內圈資料,直到填寫完畢
* @param a
* @param row
* @param col
* @param i
* @param j
*/
private static void fill(int [][] a,int row,int col,int i,int j) {
int n=row*col;
for(int c=0;c<=col-1;c++) { //橫向填充數值
a[i][j+c]=n-c; //在首行從左至右填值
if(row!=1)
a[i+row-1][j+c]=n-(col*2+row-3)+c; //如果不只1行,在末行從左至右填值
}
for(int r=0;r<row-2;r++) { //豎向填充數值
a[i+row-2-r][j]=a[i+row-1][j]-r-1; //在首列從下往上填值
if(col!=1) //如果不只1列,大末列從下往上填值
a[i+row-2-r][j+col-1]=a[i+row-1][j+col-1]+r+1;
else //否則覆蓋首列資料
a[i+row-2-r][j]=a[i+row-1][j]+r+1;
}
if(row-2>0 && col-2>0) fill(a,row-2,col-2,i+1,j+1); //如果還沒填完資料,則遞迴填寫
}
/**
* 列印二維數組
* @param a
*/
private static void print(int[][] a) {
for(int i=0;i<a.length;i++) {
for(int j=0;j<a[0].length;j++) {
System.out.printf("%4d",a[i][j]);
}
System.out.println();
}
}
}