算法-数组:螺旋数字排列

/****************************************
 * http://community.csdn.net/Expert/topic/3848/3848013.xml?temp=8.248538E-02
 *   左移:left(x+,y);
 *   右移:right(x-,y);
 *   上移:up(x,y-);
 *   下移:down(x,y+)
 *   --------------------------
 *       0 1 ...     N(x)
 *       0* * * * * * *                        右 右 右 右 。 。 。 右 下
 *       1* * * * * * *                        右                        下
 *       .* * * * * * *                        上                        下
 *       .* * * * * * *                          。。。。。。。。。。。
 *        * * * * * * *                        上                        下
 *        * * * * * * *                        上                        下
 *    (y)M* * * * * * *                        上 左 左 左 。 。 。 左 左
 *   --------------------------
 *   注意坐标:(x,y) 和数组[y],[x];是反过来的,呵呵。我刚才搞错了.
 *            比如右下角的 坐标是(N,M); 数组是[M][N]
 ***************************************/
import java.lang.String;

class Point {
    private int x = 0;
    private int y = 0;
    Point(int pX, int pY) {
        setPoint(pX, pY);
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    public void setPoint(int pX, int pY) {
        x = pX;
        y = pY;
    }
    public Point moveBy(int mX, int mY) {
        setPoint( (x + mX),(y + mY) );
        return this;
    }
    public Point moveBy(Point moveValue) {
        //return new Point( (this.getX()+moveValue.getX()), (this.getY()+moveValue.getY()) );
        this.setPoint( (this.getX()+moveValue.getX()), (this.getY()+moveValue.getY()) );
        return this;
    }
}

class Method extends Point {
    private static int x = 0;
    private static int y = 0;
    private final int N;//x.limit;
    private final int M;//y.limit;
    private static final Point moveLeft   = new Point(-1, 0);
    private static final Point moveRight  = new Point( 1, 0);
    private static final Point moveUp     = new Point( 0,-1);
    private static final Point moveDown   = new Point( 0, 1);

    Method(int pX, int pY) {
        super(0,0);
        setPoint(0,0);
        N = pX;
        M = pY;
    }
    public Point nextPoint(Point currentPoint) {
        int nIndex=-1,        //当前元素所在圈(从外到内),也是下面四值的最小值+1
            gapXs=0,        //与所在圈起点x的差值
            gapXe=0,        //与所在圈终点x的差值
            gapYs=0,        //与所在圈起点y的差值
            gapYe=0;        //与所在圈终点y的差值
        boolean bLeft        = false,
                bRight        = false,
                bTop        = false,
                bBottom        = false;
        Point moveWhere = new Point(0,0);

        gapXs = currentPoint.getX() - 0;
        gapXe = N - currentPoint.getX();
        gapYs = currentPoint.getY() - 0;
        gapYe = M - currentPoint.getY();

        do {
            bLeft   = gapXs>(nIndex+1)?false:true;
            bRight  = gapXe>(nIndex+1)?false:true;
            bTop    = gapYs>(nIndex+1)?false:true;
            bBottom = gapYe>(nIndex+1)?false:true;
            nIndex++;//从-1开始做++
        }while( !(bLeft||bRight||bTop||bBottom) );

        //顺时针螺旋,判断先后为:bTop -> bRight -> bBottom -> bLeft;
        //逆时针螺旋,判断先后为:bTop <- bRight <- bBottom <- bLeft;
        if( bTop ) {                                //上面
            if( bRight )                                //右上角,下移
                moveWhere = moveDown;
            else                                        //上边,右移
                moveWhere = moveRight;
        }
        else if( bRight ) {                        //右面
            if( bBottom )                                //右下角,左移
                moveWhere = moveLeft;
            else
                moveWhere = moveDown;                        //右边,下移
        }
        else if( bBottom ) {                        //下面
            if( bLeft )                                        //左下角:特殊
                if( (currentPoint.getY()-nIndex)==1 )                //本圈轮回结束,重新右移
                    moveWhere = moveRight;
                else                                                //左下角,上移动
                    moveWhere = moveUp;
            else
                moveWhere = moveLeft;                        //下边,左移
        }
        else {                                        //左面
            if( (currentPoint.getY()-nIndex)>=2 )        //左边,上移
                moveWhere = moveUp;
            else                                        //差值为1时,表本圈轮回结束
                moveWhere = moveRight;
        }
        return currentPoint.moveBy(moveWhere);        //返回currentPoint自身(已经重置),
    }
}

public class Arr {

    public static void main(String [] args) {

        final int DEF_ARR_N = 7;
        final int DEF_ARR_M = 7;
        int arrX = 0;
        int arrY = 0;

        int nNumArgs = args.length;
        if( nNumArgs >=2 ) {
            arrX = Integer.parseInt(args[0]);
            arrY = Integer.parseInt(args[1]);
        }
        else {
            arrX = DEF_ARR_N;
            arrY = DEF_ARR_M;
        }

        int nVal    = 0;
        int [][] aa = new int[arrY][arrX];
        Point  test = new Point(0,0);
        Method meth = new Method(arrX-1,arrY-1);

        System.out.println("start-------------------------------------------");
        for(int i=1; i<=arrX*arrY; i++) {
        //  System.out.println("aa["+(test.getY())+"]["+(test.getX())+"]="+i);
            aa[test.getY()][test.getX()] = i;
            test = meth.nextPoint(test);
        }

        String printStr;
        for(int i=0; i<arrY; i++) {
            System.out.print("        ");
            for(int j=0; j<arrX; j++) {
                printStr = ("       "+aa[i][j]);
                System.out.print(   printStr.substring( (printStr.length()-7), printStr.length() )   );
            }
            System.out.println("");
        }
    }
}

D:/MyJava>java  Arr 5 6
start-------------------------------------------
       1        2       3      4       5
      18     19     20     21      6
      17     28     29     22      7
      16     27     30     23      8
      15     26     25     24      9
      14     13     12     11     10
D:/MyJava>


我的站点:www.fbug.cn


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值