顺时针 蛇形队列

来源:互联网 发布:java 保留4位小数 编辑:程序博客网 时间:2024/05/16 07:43

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package shexingduilie;

import java.util.List;
import java.util.ArrayList;

/**
 *
 * @author Administrator
 */
public class SheXingDuiLie {
    //获取输入的值,或许说生成要输出的值更加确切吧。
    public static List<String> getInputValues() {
        List<String> inputValues = new ArrayList<String>();
        for (int i = 0; i < 111; i++) {
            inputValues.add(i, i + "");
        }
        return inputValues;
    }
   
    //获取蛇形队列的总圈数,最内部为第0圈,然后依次递增
    public static int getZongQuanShu(int inputValuesAmount) {
        if (inputValuesAmount < 0) {
            return -1;
        }
        Double n = Math.sqrt(inputValuesAmount);
        n = ((n - 1) / 2);
        int m = n.intValue();
        return m < n ? m + 1 : m;
    }
   
    //方法1,这是跟着蛇形队列的步伐,从0开始把每个数列位置(输入数列inputValues中的位置)遍历一遍,
    //将每个数列位置放到二维数组(输入结果用,以左下角为0,0点)合适的位置
    public static int[][] getResultPositionByCW_WithType1(int ZongQuanShu) {
        int n = ZongQuanShu;
        int[][] resultPosition = new int[2 * n + 1][2 * n + 1];
        for (int i = 0; i <= n; i++) {
            if (0 == i) {
                resultPosition[n][n] = 0;
                continue;
            }
            int x = n - i + 1;// 每一圈初始位置的x坐标
            int y = n + i;// 每一圈初始位置的y坐标
            int position = (int) Math.pow(2 * i - 1, 2); // 一圈起始位置所代表的数列位置
            for (int turn = 0; turn < 4; turn++) {
                for (int step = 0; step < 2 * i; step++) {
                    switch (turn) {
                        case 0:
                            if (step == 0) {
                                resultPosition[x][y] = position;
                                position++;
                                break;
                            }
                            x++;
                            resultPosition[x][y] = position;
                            position++;
                            break;
                        case 1:
                            y--;
                            resultPosition[x][y] = position;
                            position++;
                            break;
                        case 2:
                            x--;
                            resultPosition[x][y] = position;
                            position++;
                            break;
                        case 3:
                            y++;
                            resultPosition[x][y] = position;
                            position++;
                            break;
                    }


                }
            }
        }
        return resultPosition;
    }

    //方法2,以输出图形左下角为原点(0,0),根据x,y与数列位置的关系,算出每个点的数列位置
    public static int[][] getResultPositionByCW_WithType2(int ZongQuanShu) {
        int n = ZongQuanShu;
        int m = -1;//当前圈数;
        int[][] resultPosition = new int[2 * n + 1][2 * n + 1];
        for (int y = 0; y <= 2 * n; y++) {
            for (int x = 0; x <= 2 * n; x++) {
                if (x == n && y == n) {
                    resultPosition[x][y] = 0;
                    continue;
                }
                //距起始位置(n,n)的垂直或水平距离中最大者极为所在圈数,
                if (x + y <= 2 * n) {
                    m = x < y ? (n - x) : (n - y);
                }
                if (x + y > 2 * n) {
                    m = x > y ? (x - n) : (y - n);
                }
                //左下角的数列位置是4m的平方+2m,计算可知
                int zuoXia = (int) (4 * Math.pow(m, 2) + 2 * m);
                //右上角的数列位置是4m的平方-2m,计算可知
                int youShang = (int) (4 * Math.pow(m, 2) - 2 * m);
                //这两点是基准,其他的均可有这两点根据x,y的值算出
                if (x + y <= 2 * n) {
                    if (x == y) {
                        resultPosition[x][y] = zuoXia;
                    }
                    //n-m为当前圈左下角据原点的水平和垂直距离
                    if (x > y) {  
                        //x - (n - m)为当前点距当前圈左下角的水平距离,下面的算式类似
                        resultPosition[x][y] = zuoXia - (x - (n - m));
                    }
                    if (x < y) {
                        resultPosition[x][y] = zuoXia + (y - (n - m));
                    }
                }
                if (x + y > 2 * n) {
                    if (x == y) {
                        resultPosition[x][y] = youShang;
                    }
                    //n+m为当前圈右上角据原点的水平和垂直距离
                    if (x > y) {
                        resultPosition[x][y] = youShang + ((n + m) - y);
                    }
                    if (x < y) {
                        resultPosition[x][y] = youShang - ((n + m) - x);
                    }
                }
            }
        }
        return resultPosition;
    }
   
    //格式化输入的值,将长度不足的填充空格符,为了输入美观
    public static int formatInputValue(List<String> inputValues) {
        int bigLength = 0;
        String appendString = "                                                                                                      ";
        for (String s : inputValues) {
            if (s.length() > bigLength) {
                bigLength = s.length();
            }
        }
        for (int i = 0; i < inputValues.size(); i++) {
            StringBuffer sb = new StringBuffer(inputValues.get(i));
            if (sb.length() < bigLength) {
                if (appendString.length() < bigLength - sb.length()) {
                    sb.insert(0, appendString, 0, appendString.length());
                } else {
                    sb.insert(0, appendString, 0, bigLength - sb.length());
                }
                inputValues.set(i, sb.toString());
            }
        }
        return bigLength;
    }
   
    //打印输入值
    public static void printInputValue(List<String> inputValues) {
        if (null == inputValues || inputValues.isEmpty()) {
            return;
        }
        int amount = inputValues.size();// 输入值的数量
        int n = getZongQuanShu(amount);// 总圈数

        int bigLength = formatInputValue(inputValues);//格式化输入的值

//        int[][] resultPosition = getResultPositionByCW_WithType1(n);
        int[][] resultPosition = getResultPositionByCW_WithType2(n);
        for (int i = 2 * n; i >= 0; i--) {
            for (int j = 0; j <= 2 * n; j++) {
                int position = resultPosition[j][i];// 要输出数载列表中的位置
                if (position >= amount) {
                    StringBuffer sb = new StringBuffer();
                    String appendString = "                                                                                                      ";
                    if (bigLength > appendString.length()) {
                        System.out.print(appendString);
                    } else {
                        sb.insert(sb.length(), appendString, 0, (bigLength - sb.length()));
                        System.out.print(sb.toString());
                    }

                } else {
                    System.out.print(inputValues.get(position));
                }
                System.out.print(" ");
            }
            System.out.println();
        }
    }
   
    //启动
    public static void main(String[] args) {
        printInputValue(getInputValues());
    }
}

原创粉丝点击