int i=5;
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
int i=6
1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11
请问应该怎么打印出上面的数字,并且这样排列?
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
int i=6
1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11
请问应该怎么打印出上面的数字,并且这样排列?
class snakePrint {
static int length = 7;
static int value = 1;
static int[][] snake = new int[length][length];
static Direction lastDirection = Direction.Right;
static enum Direction {
Right, Down, Left, Up;
}
public static void initialArray() {
int row = 0, line = 0;
for (int c = 0; c < length * length; c++) {
snake[row][line] = value;
lastDirection = findDirection(row, line);
switch (lastDirection) {
case Right:
line++;
break;
case Down:
row++;
break;
case Left:
line--;
break;
case Up:
row--;
break;
default:
System.out.println("error");
}
value++;
}
}
static Direction findDirection(int row, int line) {
Direction direction = lastDirection;
switch (direction) {
case Right: {
if ((line == length - 1) || (snake[row][line + 1] != 0))
direction = direction.Down;
break;
}
case Down: {
if ((row == length - 1) || (snake[row + 1][line] != 0))
direction = direction.Left;
break;
}
case Left: {
if ((line == 0) || (snake[row][line - 1] != 0))
direction = direction.Up;
break;
}
case Up: {
if (snake[row - 1][line] != 0)
direction = direction.Right;
break;
}
}
return direction;
}
public static void main(String[] args) {
initialArray();
// display.....
for (int i = 0; i < length; i++) {
for (int j = 0; j < length; j++) {
System.out.print(snake[i][j] + " ");
}
System.out.println();
}
}
}
class Direction {
public static final int RIGHT = 1;
public static final int DOWN = 2;
public static final int LEFT = 3;
public static final int UP = 4;
public static final int[] DirectionArray = {RIGHT, DOWN, LEFT, UP};
}
class DirectsWithInteger {
private static int[] directs = null;
private static int[] prints = null;
private static int[] getDirects(int n) {
directs = new int[2*n-1];
for(int i=0; i<directs.length; i++) {
if(0 == i) {
directs[i] = n;
}else {
if(0 == i%2) {
directs[i] = n - i/2;
}else {
directs[i] = n - (i+1)/2;
}
}
}
return directs;
}
public static int[] getPrintDirects(int n) {
directs = getDirects(n);
prints = new int[n*n];
int startIndex = 0;
for(int i=0; i<directs.length; i++) {
for(int j=0; j<directs[i]; j++) {
prints[startIndex++] = Direction.DirectionArray[i%Direction.DirectionArray.length];
}
}
return prints;
}
}
//MainClass
public class ScrewRectangle {
public static final int N = 10;
public static int[] direction = Direction.DirectionArray;
public static int[] directs = DirectsWithInteger.getPrintDirects(N);
public static int printDirection = direction[0];
public static void main(String[] args) {
int[][] p = printScrew();
System.out.println("Init-N=" + N);
for(int i=0; i<p.length; i++) {
for(int j=0; j<p[i].length; j++) {
System.out.print(p[i][j] + "\t");
}
System.out.println();
}
}
public static int[][] printScrew() {
System.out.println();
int[][] a = new int[N][N];
int xIndex = 0;
int yIndex = 0;
for(int i=0; i<N*N; i++) {
a[yIndex][xIndex] = i+1;
if(i == N*N-1) {
break;
}
if(1 == directs[i+1]) {
xIndex++;
}else if(2 == directs[i+1]) {
yIndex++;
}else if(3 == directs[i+1]) {
if(xIndex > 0) {
xIndex --;
}
}else {
yIndex--;
}
}
return a;
}
}
//Result:
//Init-N=10
//1 2 3 4 5 6 7 8 9 10
//36 37 38 39 40 41 42 43 44 11
//35 64 65 66 67 68 69 70 45 12
//34 63 84 85 86 87 88 71 46 13
//33 62 83 96 97 98 89 72 47 14
//32 61 82 95 100 99 90 73 48 15
//31 60 81 94 93 92 91 74 49 16
//30 59 80 79 78 77 76 75 50 17
//29 58 57 56 55 54 53 52 51 18
//28 27 26 25 24 23 22 21 20 19
class Direction定义了静态int常量和一个静态int数组,并且是逆时针顺序
class DirectsWithInteger定义了两个静态int数组:directs, prints。其中directs保存int N平方的分解:
例如5 5*5=25 = 5 + 4 + 4 + 3 + 3 + 2 + 2 + 1 + 1;
再如6 6*6=36 = 6 + 5 + 5 + 4 + 4 + 3 + 3 + 2 + 2 + 1 + 1;
另外的prints保存int i从0到N*N-1的打印方向如果 i如果落在了directs的第i个元素里,对应的打印方向为Direction.DirectionArray[i%Direction.DirectionArray.length],从而得以循环RIGHT - > DOWN - > LEFT - > UP - > ...
在main方法所在的类里边定义一个返回一个二维数组的方法,返回的二维数组记录了将要打印的顺序:
如果向右走对应的游标xIndex++,向下则yIndex++,向左xIndex--,向上yIndex--...
由于prints已经定义了从0到N*N-1对应的方向,所以一路走下来就完成了对返回数组的赋值,打印即可
另外如果想要逆时针顺序的,只要把代码a[yIndex][xIndex] = i+1;换为a[xIndex][yIndex] = i+1;即可,起点默认在(0,0),换起点了对应的修改游标加减的方法即可...
仅供参考,多多指正if(1 == directs[i+1]) {
xIndex++;
}else if(2 == directs[i+1]) {
yIndex++;
}else if(3 == directs[i+1]) {
xIndex --;
}else {
yIndex--;
}头部定义的几个没用到的变量,可以注释掉的
请参见
http://blog.csdn.net/icy_csdn/archive/2010/03/09/5359153.aspx
public static void main(String[] args)throws Exception{ int size=10;
SpeedState sps=new SpeedState();
int[][] a=new int[size][size];
for(int i=1,x=0,y=0,max=size*size;i<=max;i++){
//output at current position
a[x][y]=i;
//get next position
int[] state;
int nxtX,nxtY;
while(i<max){
state=sps.getState();
nxtX=x+state[0];
nxtY=y+state[1];
if((nxtX>=0&&nxtX<=size-1)
&&(nxtY>=0&&nxtY<=size-1)
&&(a[nxtX][nxtY]==0)){
x=nxtX;
y=nxtY;
break;
}
sps.nextState();
}
}
//print Matrix
for(int i=0;i<size;i++){
for(int j=0;j<size;j++){
System.out.print(String.format("%-4s",a[i][j]));
}
System.out.print('\n');
}
}}class SpeedState{
private int[][] state={//x,y
{0 ,1 },
{1 ,0 },
{-1 ,0 },
{0 ,-1 }
};
private int stateIndex;
public SpeedState(){
stateIndex=0;
}
public int[] getState(){
return state[stateIndex];
}
public void nextState(){
stateIndex++;
stateIndex%=4;
}
}
2.路径的规律 :
a。填写的几个路径可以简单的归纳成四种,从左向右——针对数组来说,就是横坐标不动,纵坐标增加1。其他三个基本路径是从右向左,从上向下和从下向上。
b。针对这个题目,这几个基本的路径应该是 (从左向右)-(从上向下)-(从右向左)-(从下向上)然后循环。
c. 如果定义一个int N , 那么结果产生的数组是一个 N*N 的数组,数组产生的具体路径是 (从左向右移动N位)- -(从上向下移动N-1位)-(从右向左N-1位)-(从下向上移动N-2位)
也就是步数的变化是 {N,N-1,N-1,N-2,N-2...1,1} (我的例子中这个步骤的规律的产生,没有具体些)我在我写的方法中,首先 定义了一个结果类 ,其中 int[][] 用于存放结果的代码,一些变量用来记录填写这个结果用到的状态,比如第几行(row)第几列(col)填写数字(fnum)几,请看程序:(get,set方法我就省去了)
public class Result {
private int row; //记录向数组中填写数字的时候,要填写位置的横坐标
private int col; //记录向数组中填写数字的时候,要填写位置的纵坐标
private int conut = 1; //要填写的步数。如向右填写3步,如果默认从第一行第一列开始填写,则[0][0],[0][1],[0][2]填写数字
private int len; //len维数组
private int fnum = 1 ; //填写的数组,默认从0开始,增加1。当然这个起始值和增量可以由客户端定义,这里先省去了。
private Toward toward; //填写数字的方向。
enum Start{
UPPERLEFT , UPPERRIGHT , UNDERLEFT , UNDERRIGHT } ;
//起始位置 UPPERLEFT 左上角 ..类推..这个参数可以了去掉,换成两个int值,用来定义起始位置,这样的话,就可以不局限于只从数组的四个角上开始
private int[][] result; //记录填写的结果
public Result(){ //默认是一个 5*5的数组,起始位置在左上角
this.row = 0 ;
this.col = -1 ;
this.len = 5 ;
toward = new RightToward();
result = new int[5][5];
}
public Result(int len , Start start ){ //可以传递进来参数 (len维数组,起始位置)
this.len = len ;
result = new int[len][len]; //运行结果是一个 len * len 的二维数组
if(Start.UPPERLEFT.equals(start)){ //如果起点在数组的左上角,则row=0,col=-1,(先移动后填写数字),并且第一步要向右走,第一步移动到[0][0],填写....下面类推
this.row = 0 ;
this.col = -1 ;
toward = new RightToward();
}else if(Start.UPPERRIGHT.equals(start)){
this.row = -1;
this.col = len - 1 ;
toward = new DownToward();
}else if(Start.UNDERLEFT.equals(start)){
this.row = len ;
this.col = 0;
toward = new UpToward();
}else{
this.row = len - 1 ;
this.col = len ;
toward = new LeftToward();
}
}
public void fillNum(){
try{
this.result[row][col] = fnum ;
}catch(Exception e){
//数组越界
e.printStackTrace();
}
}
public void systemResult(){
for(int r = 0 ; r < len ; r ++){
for(int c = 0 ; c < len ; c ++){
System.out.print(result[r][c] + " ");
}
System.out.println();
}
} public void execute(){
this.toward.handle(this);
}
}下面我们要把填写路径的方法提取出来,首先定义一个抽象类:public abstract class Toward {
public abstract void handle(Result result);
public abstract void changeDirection(Result result);
}
然后定义具体四个填写路径的类,例如从左到右:public class RightToward extends Toward { @Override
public void changeDirection(Result result) {
// TODO Auto-generated method stub
result.setToward(new DownToward()); //从左到右填写完了,要告诉结果类,下一步要从上向下填写了,DownToward()这个类就是从上向下填写的类
} @Override
public void handle(Result result) {
for(int step = 0 ; step < result.getConut() ; step ++){
result.setRow(result.getRow()); //先移动
result.setCol(result.getCol()+1);
result.fillNum(); //后填写
result.setFnum(result.getFnum()+1); //这里的+1可以修改,将自增值自己定义
}
this.changeDirection(result);
// TODO Auto-generated method stub
}}其他三个填写路径的类差不多,请参考第一个路径即可。changeDirection(Result result) 中要注意他们的顺序,(从左向右)-(从上向下)-(从右向左)-(从下向上)-(从左向右)好了,来看看我们的客户端吧:public class Client {
public static void main(String[] args){
int arrlen = 6 ;
Result result = new Result(arrlen , Result.Start.UPPERLEFT);
//判断 arrlen > 0
//int[] route = new int[2*arrlen - 1];
int[] route = {6,5,5,4,4,3,3,2,2,1,1};
for(int i = 0 ; i < route.length ; i++){
result.setConut(route[i]);
result.execute();
}
result.systemResult();
}
}其中 int[] route = {6,5,5,4,4,3,3,2,2,1,1};
应该是根据 int arrlen = 6 ; 得来的,这个应该好弄,是有规律的,具体我就不在这里写了。
运行一下看看结果:
1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11
还行...我们换一下 Result result = new Result(arrlen , Result.Start.UNDERLEFT);
让它从左下角开始,结果:
6 7 8 9 10 11
5 24 25 26 27 12
4 23 34 35 28 13
3 22 33 36 29 14
2 21 32 31 30 15
1 20 19 18 17 16
也还行。不过我现在想要这种的了:
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
21 22 23 24 25
这种貌似就不能实现了...怎么办... 童鞋们想想...想出来的童鞋,楼主送香吻一枚。要是这种呢:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16童鞋们想想...想出来的童鞋,楼主送....嘿嘿嘿嘿...
可能要想的太复杂了,不要介意
再吼一声:给我打印个H电影出来,然后电脑屁颠儿屁颠儿的跑了半天,然后冒烟儿了!!!
O(∩_∩)O哈哈~,玩笑了~~~
(男人,女人)
(男人,男人,女人)
(list<男人> , list<女人>)
...方法名相同,参数不同,这叫什么...童鞋回答..