算法--地点线路问题

算法--地铁线路问题


 

 废话不说,上代码,都有注释,就不解释什么了

import java.util.Scanner;

public class train {
    public static String[] one = {"A10", "A11", "A12", "A13", "A14", "A15", "A16", "A17", "A18", "A19", "A20", "A21", "A22", "A23", "A24", "A25", "A26"};
    public static String[] two = {"B1", "B2", "B3", "A12", "B4", "B5", "B6", "B7", "B8","B9", "B10", "A24", "B11", "B12", "B13", "B14"};
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入开始站");
        String trainbegin = sc.next();
        System.out.println("请输入结束站");
        String trainend  = sc.next();
        train_fround_minload(trainbegin,trainend);
    }

    /**
     * 判断属于哪个类型,进行调用
     * 1.全部为A开头
     * 2.有A有B开头
     * 3.全部为B开头
     * 注:将AB和BB开头分开,可以增加代码可读性
     * @param trainbegin
     * @param trainend
     */
    public static void train_fround_minload(String trainbegin,String trainend){
        switch (analyse(trainbegin,trainend)){
            case "AA":AA(trainbegin,trainend); ;break;
            case "AB":AB(trainbegin,trainend);break;
            case "BB":BB(trainbegin,trainend); ;break;
            default:break;
        }
    }

    /**
     *
     * @param trainbegin  开始站次
     * @param trainend  结束站次
     */
    public static void AA(String trainbegin,String trainend){
        String[] as1 = trainbegin.split("A");
        String[] as2 = trainend.split("A");
        int be =Integer.parseInt(as1[1]);
        int en = Integer.parseInt(as2[1]);
        if (be < 10 || en > 26){
            System.out.println("err:请输入航班线内的站次!");
        }else {
            int len = en - be;
            System.out.println();
            System.out.println("------------------");
            System.out.println("一共走了" +Math.abs(len) + "站");
            System.out.println("分别是:");
            if (be == en ){
                System.out.println("请下车");
            }else{
                if (en > be){
                    for (int i = 0; i <= len; i++) {
                        System.out.print("A" + (be + i) + "  ");
                    }
                }else{
                    for (int i = 0; i <= Math.abs(len); i++) {
                        System.out.print("A" + (be - i) + "  ");
                    }
                }

            }

        }
    }
    public static void AB(String trainbegin,String trainend){
        //如果是A12或者A24的,就说明是BB的情况,调用BB
        if (trainbegin.equals("A12") || trainbegin .equals( "A24") || trainend .equals("A12") ||trainend .equals( "A24")){
            BB(trainbegin,trainend);
        }else{
            //首先运用拆分看第一个是否为A,因为其他情况都已经讨论过了,所以,只有AB或BA的两种情况


            int betwo = printArray(two, trainbegin);
            int entwo = printArray(two, trainend);
            String[] as1 = trainbegin.split("A");
            //情况--AB    1.as[1].length 的长度等于2代表是A开头,反之不是
            if (as1[1].length() == 2){
                int beone = printArray(one, trainbegin);
                if (beone <= 2 ){
                    AA(trainbegin,"A12");
                    AB("A12",trainend);
                }else{
                    if (beone >= 14){
                        AA(trainbegin,"A24");
                        AB("A24",trainend);
                    }else{
                        if ((beone-2)+minlen("A12",trainend) <= (20- ((beone-2)+minlen("A12",trainend)))){
                            AA(trainbegin,"A12");
                            AB("A12",trainend);
                        }else{
                            AA(trainbegin,"A24");
                            AB("A24",trainend);
                        }
                    }
                }
            }else{
                int enone = printArray(one, trainend);
                if (enone <= 2){
                    AB(trainbegin,"A12");
                    AA("A12",trainend);
                }else{
                    if(enone >= 14){
                        AB(trainbegin,"A24");
                        BB("A24",trainend);
                    }else{
                        if (minlen("A12",trainbegin)+(enone-2) <= (20 - (minlen("A12",trainbegin)+(enone-2)))){
                            BB(trainbegin,"A12");
                            AB("A12", trainend);
                        }else{
                            BB(trainbegin,"A24");
                            AB("A24",trainend);
                        }
                    }
                }
            }
        }
    }

    public static int minlen(String what,String trainplace){
        int i = -1;
        if(what.equals("A12")){
            i = printArray(two,trainplace) - printArray(two,what);
            if (i>0){
                i = Math.min(i,16-i);
                return i;
            }else{
                i = printArray(two,what) - printArray(two,trainplace);
                i = Math.min(i,16-i);
                return i;
            }
        }
        System.out.println("error!");
        return i;
    }

    /**
     * 全部以B开头的一定是走二号线,所以单独列出来,进行逻辑的判断,这个也可以有AB开头的进行调用
     * @param trainbegin
     * @param trainend
     */
    public static void BB(String trainbegin,String trainend){
        int be = printArray(two,trainbegin);
        int en = printArray(two,trainend);
        //将问题拆成下标大于8和小于8,分别对应的是按数组走和不按数组走
        if (Math.abs(en-be) <= 8 ){
            //如果en大于be就代表正向,小于代表逆向
            System.out.println("一共走了"+Math.abs(en-be)+"站");
            if (en > be){
                System.out.println("分别是:");
                for (int i = 0 ;i <= Math.abs(en-be);i++){
                    System.out.print(two[be+i]+"  ");
                }
            }else{
                System.out.println("分别是:");
                for (int i = 0 ;i <= Math.abs(en-be);i++){
                    System.out.print(two[be-i]+"  ");
                }
            }
        }else{
            int count = Math.abs(Math.abs(en - be)-16);
            System.out.println("一共走了"+count+"站");
            if (en > be){
                for (int i = 0 ;i <= count ; i++){
                    if (be - i >= 0) {
                        System.out.print(two[be - i]+"  ");
                    }
                    else{
                        System.out.print(two[16+be-i]+"  ");
                    }
                }
            }else{
                for (int i = 0 ;i <= count; i++){
                    if (be + i <= 15){
                        System.out.print(two[be+i]+"  ");
                    }else{
                        System.out.print(two[be+i-16]+"  ");
                    }
                }
            }


        }
    }

    /**
     *
     * @param trainbegin
     * @param trainend
     * @return 判断相对应的类型,为找到返回null
     */
    public static String analyse(String trainbegin,String trainend) {
        String sbegin = String.valueOf(trainbegin.charAt(0));
        String send = String.valueOf(trainend.charAt(0));
        if (sbegin.equals("A")  && send .equals("A")) {
            return "AA";
        } else if ((sbegin .equals("A") && send .equals("B")) || (sbegin .equals("B") && send .equals("A"))) {
            return "AB";
        } else if (sbegin .equals("B") && send.equals("B")) {
            return "BB";
        }
        return null;
    }

    /**
     *
     * @param array 要查找的数组
     * @param value 查找数组中的元素
     * @return 找到返回下标,未找到返回-1
     */
    public static int printArray(String[] array,String value){
        for(int i = 0;i<array.length;i++){
            if(array[i].equals(value)){
                return i;
            }
        }
        return -1;//当if条件不成立时,默认返回一个负数值-1
    }

}
地铁线路

 

这个算法的更优解是使用广度优先算法,创建一个二维数组,里面分别放入相应的左右连接,然后依此查找,会比我写的直接查找方便很多,这个简单问题可以剩下来50行代码左右吧,越复杂,就越简洁

posted @ 2022-04-29 11:50  七色angel  阅读(27)  评论(0编辑  收藏  举报