• 北京地铁规划项目总结


    一、项目介绍

      GitHub链接:https://github.com/Magazinediver/Subway

      核心算法:Dijkstra算法

      编写语言:Java

      需求分析:

        1.subway.txt导入地铁线路信息,routine.txt输出地铁线路信息

        2.对地铁行程规划(最短路径查询),并输出

        3.输出地铁信息 1线路信息2站点信息

      

    二、文件导入方式设计

      2.1导入文本txt格式

    24                         //线路总数
    
    1                           //线路编号
    23                         //线路中站点数目
    一号线                    //线路名
    一号线 苹果园 否       //格式: 线路名 站点名 是否换乘,若换乘则列出站点名
    一号线 古城 否
    一号线 八角游乐园 否
    一号线 八宝山 否
    一号线 玉泉路 否
    一号线 五棵松 否
    一号线 万寿路 否
    一号线 公主坟 十号线
    一号线 军事博物馆 九号线
    一号线 木樨地 否
    一号线 南礼士路 否
    一号线 复兴门 二号线
    一号线 西单 四号线
    ......
     

           2.2 java文件导入设计

        1.导入时先按照文档中第一个数字,即线路总数x,建立for循环,获取有x条线路的line_list

        2.再按照每条线路的第一行的数字,获取线路id

        3.利用每条线路中的第二行,取得每条线路中的站点总数y,建立for循环,获取有y个站点的station_list,即每条线路中的站点列表

        4.利用每条线路中的第三行,取得每条线路中的站点中文名称

        5.后面即是地铁站点的输入格式:线路名 站点名 是否换乘,若换乘则列出站点名

           其中先按空格分开一行,存入String s[] ,s[0]所属线路,s[1]站点名,s[2]是否有换乘,若S[2]不是“否“(非换乘站),就将S[2]按照“,”分离,存入String s1[],即trans_list

       2.3java文件导入概念图

        

       2.4java文件导入代码实现

          

     while((str=bufferedReader.readLine())!=null) {
             if(str.equals(String.valueOf(j)))//
             {
                    Line a  = new Line();
                    int k = Integer.parseInt(bufferedReader.readLine());//
                    a.setLname(bufferedReader.readLine());
                    for(int h=0;h<k;h++)
                    {
                           Station b = new Station();
                           if((str1=bufferedReader.readLine())!=null)
                           {
                                  String[] s = str1.split(" ");                                   
                                  b.setLine(s[0]);
                                  b.setSname(s[1]);
                                  if(!s[2].equals("否"))
                                  {
                                         String[] s1 = s[2].split(",");
                                         b.setStationrans(s1);
                                         u=0;
                                         for(int p=0;p<kb.length;p++)
                                         {
                                               if(kb[p].equals(b.getSname()))
                                               {
                                                      u=1;
                                               }
                                         }
                                         if(u!=1) {
                                               kb[t] = b.getSname();
                                               t++;
                                         }
                                  }
                           }
                           a.setStation(b);
                    }
                    list.add(a);
                    j++;
            }
            
            return list;
    }

    三、存储结构设计

      3.1.无向图站点结构设计

        1.station作为node

        2.每个node之间有边连接,默认权值99,若是两站链接则权值设为1

        3.可获得node再无向图中的序号

        4.可对图中node计数

        5.设计无向图的邻接矩阵结构

    public static List<Line> mainlist = new ArrayList<Line>();  //线路list
    protected int[][] subTrainMatrix;                                       // 邻接矩阵
    private static final int MAX_WEIGHT = 99;                         // 初始各node间距离99
    private int[] dist;                                                             //node间距离存储数组
    private List<Station> vertex = new ArrayList<Station>();  // node
    private List<Edge> edges;                                               //node间距离结构
    
    //各个方法
    public int[][] getSubTrainMatrix()                                     //get邻接矩阵
    public void setVertex(List<Station> vertices)                    //set node
    public List<Station> getVertex()                                      //get node
    public List<Edge> getEdges()                                          //get边
    public int getVertexSize()                                                //图中node数
    public int vertexCount()                                                  //node编号
    public String toString() 
    public subway(int size)
    public subway(List<Station> vertices)

           3.2无向图边结构设计

                 

     class Edge {
             private T start, dest;                        //起始站,目标站
             private int weight;                         //边权值
             public Edge()                              
             public Edge(T start, T dest, int weight)
             public String toString()
    }

           3.3站点结构

                  

    public class Station {
              public String sname;                     //站点名
              String[] trans = new String[3];             //换乘线路存储数组
              public String line;                       //所属线路名
     
              public void setSname(String sname)       //set站点名
              public String[] getStationrans()            //get站点换乘线路列表
              public void setStationrans(String[] trans)    //set站点换乘线路列表
              public String getLine()                   //get所属线路名
              public void setLine(String line)            //set所属线路名
              public String getSname()                //get所属站点名
    }

           3.4线路结构

                 

     public class Line {
              public String lname;                     //线路名
              public List<Station> station = new ArrayList<Station>();//站点列表
          
              public List<Station> getStation()          //get站点列表
              public void setStation(Station station)      //set站点列表
              public String getLname()                 //get线路名
              public void setLname(String lname)        //set站点名
    }

    四、线路及线路站点输出设计

      4.1站点输出要求

        1.能显示站点所属线路 

        2.能体现出换乘

        3.能体现路线所经过的站点数

    public static void printstation()//站点输出
    {
        for(int i=0;i<mainlist.size();i++)
        {
           if(mainlist.get(i).getLname().equals(lname))
           {
                System.out.println(mainlist.get(i).getLname());
                for(int j=0;j<mainlist.get(i).getStation().size();j++)
                {
                     System.out.print(mainlist.get(i).getStation().get(j).getSname()+" ");
                     for(int k=0;k<mainlist.get(i).getStation().get(j).getStationrans().length;k++)
                     {
                         System.out.println(mainlist.get(i).getStation().get(j).getStationrans()[k]);
                     }
                 }
              }
         }
    }
     
    
    public static void printline(String lname)//线路输出与站点输出同理

      4.2输入输出设计

        4.2.1输入设计

        输入格式

          1.获取地铁线路信息      

    java subway -map subway.txt

          2.输出地铁特定线路信息 

    java subway -a 1号线 -map subway.txt -o station.txt

          3.输出地铁线路规划信息

    java subway.subway -b 古城 T2航站楼 -map subway.txt -o routine.txt

          4.输入读取代码

             -map 参数来获得对应的自定义地铁文件

             -a 指定了用户希望查询的地铁线路

             -o 指定输出文件

             -b 指定出发站与目标站

    if(args.length==0) System.out.println("");
        for(int i=0;i<args.length;i++) {
         if(args[i].equals("-map")) {
            flag1=1;
            flag2=1;
         if(args.length<i+2) {
                System.out.println("");
            return;
        }
           mainlist =Input.getFileContext(args[i+1]);
        }else if(args[i].equals("-a")) {
            flag1=1;
            operate="-a";
        if(args.length<i+2) {
            System.out.println("格式不正确");
            return;
        }
            route=args[i+1];
        }else if(args[i].equals("-b")) {
            flag1=1;
            operate="-b";
            if(args.length<i+3) {
                System.out.println("格式不正确");
                return;
            }
            start=args[i+1];
            stop=args[i+2];
        }else if(args[i].equals("-o")) {
            flag1=1;
            output=args[i+1];
            }
        }
        if(flag1==0) {
            System.out.println("格式不正确");
            return;
        }
        else if(flag2==0) {
            System.out.println("格式不正确");
            return;
        }
        if(operate==null&&output!=null) {
            System.out.println("没有输出");
            return;
        }
        else if(operate!=null&&output!=null) {
            if(operate.equals("-a")) {
                try {
                    if(outPutRoute(route, output)==false) {
                        System.out.println("没有输出,没有此线路");
                        return;
                    }
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }else if(operate.equals("-b")) {
                if(start.equals(stop)) {
                    System.out.println("出发站与到达站不能相同!!!!!");
                        return;
                    }
                    if(Mainoutput(start, stop, output)==false) {
                        System.out.println("没有输出,无法到达");
                        return;
                    }
                }
            }        
        }                

        4.2.2输出设计

        输出中的站点会携带所属线路

        两个站点间会用->连接

        最后会输出经过的站点数

        控制台中输出

             

                  文件输出设计

             

    五、测试及遇到的问题与解决方法

      5.1输入上的问题

        1.出发站与到达站相同  

        

    if(start.equals(stop)) {
                    System.out.println("出发站与到达站不能相同!!!!!");
                        return;
                    }
                    if(Mainoutput(start, stop, output)==false) {
                        System.out.println("没有输出,无法到达");
                        return;
                    }
                }

        输出:出发站与到达站不可以相同!

        2.出发站或到达站不存在或者线路不存在

        

    if(outPutRoute(route, output)==false) {
           System.out.println("没有输出,没有此线路");
           return;
    }

        3.出发站与到达站之间不可到达

    if(Mainoutput(start, stop, output)==false) {
            System.out.println("没有输出,无法到达");
            return;
    }

        4.没有所需的命令参数或输入格式错误

    
    
    if(args.length==0) System.out.println("");
        for(int i=0;i<args.length;i++) {
         if(args[i].equals("-map")) {
            flag1=1;
            flag2=1;
         if(args.length<i+2) {
                System.out.println("");
            return;
        }
           mainlist =Input.getFileContext(args[i+1]);
        }else if(args[i].equals("-a")) {
            flag1=1;
            operate="-a";
        if(args.length<i+2) {
            System.out.println("格式不正确");
            return;
        }
            route=args[i+1];
        }else if(args[i].equals("-b")) {
            flag1=1;
            operate="-b";
            if(args.length<i+3) {
                System.out.println("格式不正确");
                return;
            }
            start=args[i+1];
            stop=args[i+2];
        }else if(args[i].equals("-o")) {
            flag1=1;
            output=args[i+1];
            }
        }
        if(flag1==0) {
            System.out.println("格式不正确");
            return;
        }
        else if(flag2==0) {
            System.out.println("格式不正确");
            return;
        }
        if(operate==null&&output!=null) {
            System.out.println("没有输出");
            return;
        }
        else if(operate!=null&&output!=null) {
            ......
        }    
     

      在用if进行条件筛选,若是没有参数则会输出:格式不正确

      5.2遇到的问题

        1.在cmd中运行文件始终无法找到主类,显示无法加载

         原因:java文件在cmd中运行必须在bin目录进行带包运行

        2.在cmd中运行报错,在eclipse中确成功运行

           报错1:数组越界

           原因1:因为cmd中的编码类型为gbk(936),而我的代码是utf-8(65001),所以if无法识别,for循环无法停止,导致数组越绝

              报错2:显示乱码

           原因2: 编码类型不同,识别不了,乱码

        3.以为在eclipse中无法带参数运行,造成了很多困扰

              解决办法:eclipse中run configuration...

               

                  4.站点重复输出

          原因:因为换乘站在多条线路中都存在,导致无向图中站点重复

          解决方法:在输入时,对换乘站去重,进行筛选,若是换乘站,只在图中插入一次

          

    for(int j=0;j<mainlist.get(i).getStation().size();j++)
                {    
                    flag=0;
                    Station st = new Station();
                    st.setSname("0");
                    
                    for(int l=0;l<kb.length;l++)//非换乘站
                    {
                        if(mainlist.get(i).getStation().get(j).getSname().equals(kb1[l]))
                        {
                            flag = 1;
                        }
                        
                    }
                    if(flag==0)//是换乘站
                    {
                        st.setSname(mainlist.get(i).getStation().get(j).getSname());
                        st.setLine(mainlist.get(i).getStation().get(j).getLine());
                        st.setStationrans(mainlist.get(i).getStation().get(j).getStationrans());
                        c++;
                    }
                    else{
                        for(int p=0;p<kb.length;p++)
                        {
                            if((mainlist.get(i).getStation().get(j).getSname().equals(kb1[p]))&&(!(kb[p].equals("0"))))
                            {
                                st.setSname(mainlist.get(i).getStation().get(j).getSname());
                                st.setLine(mainlist.get(i).getStation().get(j).getLine());
                                st.setStationrans(mainlist.get(i).getStation().get(j).getStationrans());
                                kb[p]="0";
                                v++;
                            }
                        
                        }
                    }
                        
                    
                    
                    if(!st.getSname().equals("0"))
                    {
                        vertices.add(st);
                    }
                }

        5.邻接矩阵乱码,无法取得站点在list中编号

          原因:原先我写的demo中node时string类型,可使用indexof(),后来node替换成station类型,导致系统自带函数失效

          解决办法:用自己写的代码替换

          

    public int getPosInvertex(Station start) {
            for(int i=0;i<vertex.size();i++)
            {
                //System.out.println(vertex.get(i).getSname());
                    if(vertex.get(i).getSname().equals(start.sname))
                    {
                        return i;
                    }
            }
            //return vertex.indexOf(start);
            return -1;
        }

          

  • 相关阅读:
    <转> 百度空间 最大子图形问题详解
    Hdu 1124 Factorial
    Uva 457 Linear Cellular Automata
    求01矩阵中的最大的正方形面积
    【HYSBZ】1036 树的统计Count
    【SPOJ】375 Query on a tree
    【POJ】3580 SuperMemo
    【CodeForces】191C Fools and Roads
    【FOJ】2082 过路费
    【HDU】3726 Graph and Queries
  • 原文地址:https://www.cnblogs.com/ximate/p/11656105.html
Copyright © 2020-2023  润新知