数据结构---公交线路提示系统(Java后台+excel表格+web前端)

 系统大致流程:

index.jsp输入站名(点击“出示站点信息”,跳转list.jsp读取表格);
后台通过站名获得id;getIdbyname(String name)
将id反馈至dijkstra(int vs,int vf),求得最短路径以及路径上的顶点(读取文档获得图Graph);
dijkstra运行结果仍是数字,所以还要getNamebyid(int id);运用List<String>返回最短路径上的站点名称

最后反馈至succeed.jsp

源代码:

servlet层:

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import entity.Bus;
import service.busService;

/**
 * Servlet implementation class busServlet
 */
@WebServlet("/busServlet")
public class busServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    busService bus=new busService();
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        req.setCharacterEncoding("utf-8");
        String method = req.getParameter("method");
        if(method.equals("dijkstra"))
        {
            dijkstra(req,resp);
        }else if(method.equals("list"))
        {
            list(req,resp);
        }else if(method.equals("getIdbyname"))
        {
            getIdbyname(req,resp);
        }
    }

    private void getIdbyname(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * 通过name获得id
         * 用来判断输入站名在表格中是否有库存
         */    
        req.setCharacterEncoding("utf-8");
        String s = req.getParameter("start");
        String f = req.getParameter("final");
        int k1=bus.getIdbyname(s);
        int k2=bus.getIdbyname(f);
        if(k1!=-1&&k2!=-1) {//与运算,两边同时成立为真
            req.setAttribute("message", "查询成功");//setAttribute方法用于将内容保存在对象中,传到jsp中
            req.getRequestDispatcher("busServlet?method=dijkstra").forward(req,resp);//getRequestDispatcher方法用于进入下一个页面
        }else if(k1==-1||k2==-1){//或运算,两边一个成立为真
            req.setAttribute("message", "站名错误,请保证正确输入");
            req.getRequestDispatcher("index.jsp").forward(req,resp);
        }
    }
    private void list(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        List<Bus> buses = bus.readExcelList();
        req.setAttribute("buses", buses);
        req.getRequestDispatcher("list.jsp").forward(req,resp);    
    }
    
    private void dijkstra(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        String s = req.getParameter("start");
        String f = req.getParameter("final");
        int vs=bus.getIdbyname(s);
        int vf=bus.getIdbyname(f);
        List<String> stations=bus.dijkstra(vs, vf);
        req.setAttribute("stations",stations);//setAttribute方法用于将内容保存在对象中,传到jsp中
        req.getRequestDispatcher("succeed.jsp").forward(req,resp);//getRequestDispatcher方法用于进入下一个页面        
    }
    
    
}
busServlet

service层:

import java.io.IOException;
import java.util.List;

import busRoute.Dao;
import entity.Bus;

public class busService {
    Dao dao=new Dao();
    public List<String> dijkstra(int vs,int vf) throws IOException {
        // TODO 自动生成的方法存根
        
        return Dao.dijkstra(vs,vf);
    }
    public List<Bus> readExcelList() throws IOException {
        // TODO 自动生成的方法存根
        return dao.readExcelList();
    }
    public int getIdbyname(String str) throws IOException {
        int t=dao.getIdbyname(str);
        return t;
    }

}
busService

entity层:

public class Bus {
    private String name;
    private int id;
    public void setName(String name) {
            this.name=name;
    }
    public String getName() {
            return name;
    }
    public void setId(int id) {
        this.id=id;
    }
    public int getId() {
        return id;
    }
    public Bus() {
    }
    public Bus(int b,String a) {
        name=a;
        id=b;
    }   
}
Bus

dao层:

 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import entity.Bus;

public class Dao{
    

    public List<Bus> readExcelList() throws IOException {
         /**
          * 读取表格
          * 输出至前端
          */
             
             List<Bus> list = new ArrayList<>();
            String filePath="D://dns.xls";
            InputStream input = new FileInputStream(filePath);
            Workbook wb = null;
            wb = new HSSFWorkbook(input);
            //得到一个工作表对象;
            Sheet sheet = wb.getSheetAt(0);
            int rsRows = sheet.getLastRowNum();// 获取sheet表中的总行数
            
         // 遍历行
            //每一行成一个bus对象
            Bus bus=null;
            for (int i=0;i<=rsRows;i++) {
                Row row = sheet.getRow(i);
                int id=0;
               String name=null;
                //遍历行单元格,已知有两列;第一列int型id,第二列String型name
                    Cell cell1 = row.getCell(0);
                    Cell cell2 = row.getCell(1);
                    //一定要检验是否为空
                    if(cell1==null||cell1.equals(null)||cell1.getCellType()==CellType.BLANK){
                        break;
                    }else {
                        //数值型
                        id=(int) cell1.getNumericCellValue();
                        
                    }
                    if(cell2==null||cell2.equals(null)||cell2.getCellType()==CellType.BLANK){
                         break;
                    }else {
                        //字符串型
                        name= cell2.getStringCellValue();
                    }
               bus=new Bus(id,name);
               list.add(bus);
                    }      
            wb.close();//关闭
             return list;                    
        }
    
    public static  List<String>  readTxtFile(String filePath) {
        /**
         * 读取文档
         * @param filePath
         * @return
         */
                List<String> list = new ArrayList<String>();
                try {
                    String encoding = "UTF-8";
                    File file = new File(filePath);
                    if (file.isFile() && file.exists()) { 
                        InputStreamReader read = new InputStreamReader(
                                new FileInputStream(file), encoding);
                        BufferedReader bufferedReader = new BufferedReader(read);
                        String lineTxt = null;
                        while ((lineTxt = bufferedReader.readLine()) != null) {
                            if (!lineTxt.startsWith("#"))
                                list.add(lineTxt);
                        }
                        read.close();
                    } else {
                        System.out.println("找不到文件");
                    }
                } catch (Exception e) {
                    System.out.println("出错了");
                    e.printStackTrace();
                }
                return list;
          
            }
    
    
    public static String[][] createArray(String filePath){
        /**
         * 读取文档生成二维数组
         * @param filePath
         * @return
         */
            List<String> list = readTxtFile(filePath);
            System.out.println("读取成功");
            String[][] array = new String[list.size()][];
            for(int i=0;i<list.size();i++){
                array[i] = new String[list.size()];
                String linetxt=list.get(i);
                String[] myArray = linetxt.replaceAll("\\s+", "@").split("@");
                for(int j=0;j<myArray.length;j++){
                        array[i][j]=myArray[j];                                        
                }
            }
            return array;
        }
    
    
    public static int[][] str2int(String[][] str){//String型转为int型
        int a,b;
        a = str.length;
        b = str[0].length;
        int result[][] = new int[a][b];
        for(int i = 0 ; i < a ; ++ i)
            for(int j = 0 ; j < b ; ++ j) {
                result[i][j] = Integer.parseInt(str[i][j]);
            }
                
        return result;
    }
    
    public static List<String> dijkstra(int vs,int vf) throws IOException {
        /**
        * Dijkstra最短路径。
        * 即图中"节点vs"到其它各个节点的最短路径。
        * @param vs 起始节点
        * @param Graph 图
        * 将最短路径上的顶点,距离存入泛型集合list,返回
        * 注意整型用Integer不能用int
         */
        List<String> list= new ArrayList<String>();//将最短路径上的顶点,距离存入list,返回
        String[][] str= createArray("D:\\text.txt");
        //将读取的String型二维数组转化为int型       
        int[][]Graph =str2int(str);    
        int NUM = Graph[0].length;
        
        int[] prenode = new int[NUM];//前驱节点数组
        
        
        int[] path = new int[NUM];//最短距离数组
        
        
        boolean[] flag = new boolean[NUM];// 该节点是否已经找到最短路径
         
        int vnear = 0;//距离vs最近的节点
        
        //初始化
        for (int i = 0; i <path.length; i++) {
            prenode[i] = i;
            path[i] = Graph[vs][i];//顶点i的最短路径为顶点vs到i的权
            flag[i] = false;
        }
 
        flag[vs] = true;//vs自身初始化
        
        //遍历 Graph.length-1次,找出每个顶点的最短路径
        for (int v = 1; v < Graph.length; v++) {
            // 每次循环求得当前距离vs最近的顶点vnear和最短距离min
            int min = 100000;//100000表示无穷
            for (int j = 0; j < Graph.length; j++) {
                if (!flag[j] && path[j] < min) {
                    min = path[j];
                    vnear = j;
                }
            }
            //标记顶点vnear为已经获取到最短路径
            flag[vnear] = true;
            
            // 根据vnear更新vs到其他所有节点的前驱节点和最短路径
            for (int k = 0; k < Graph.length; k++) {
                if (!flag[k] && (min + Graph[vnear][k]) < path[k]) {
                    prenode[k] = vnear;
                    path[k] = min + Graph[vnear][k];
                }
            }
        }
        list.add(path[vf]+"");//+""作用是将int转化为String型
        //依次保存前驱
        for(int i=0;i<4&&prenode[vf]!=vs;i++) {//i范围根据自己表的情况
            list.add(getNamebyid(vf));
            vf=prenode[vf];
        }
        list.add(getNamebyid(vs));      
        return list;
    }
    
    public int getIdbyname(String name)throws IOException  {
        //通过name获得id
        int x=-1;
        String filePath="D://dns.xls";
         InputStream input = new FileInputStream(filePath);
            Workbook wb = null;
            wb = new HSSFWorkbook(input);
            //得到一个工作表对象;
            Sheet sheet = wb.getSheetAt(0);
            int rsRows = sheet.getLastRowNum();// 获取sheet表中的总行数            
             // 遍历行
        for (int i=0;i<=rsRows;i++) {
            Row row = sheet.getRow(i);
            int id=0;
            String flag=null;
            //遍历行单元格,已知有两列;第一列int型id,第二列String型name
                Cell cell1 = row.getCell(0);
                Cell cell2 = row.getCell(1);
                if(cell1==null||cell1.equals(null)||cell1.getCellType()==CellType.BLANK){
                    break;
                }else {
                    //数值型
                    id=(int) cell1.getNumericCellValue();
                    
                };
                if(cell2==null||cell2.equals(null)||cell2.getCellType()==CellType.BLANK){
                     break;
                }else {
                    //字符串型
                    flag= cell2.getStringCellValue();
                };    
                String a=new String(flag); 
                String b=new String(name);
                if(a.equals(b)){
                    x=id;
                };
        }                    
        wb.close();//记得关闭
        return x;
    }
    
    public static String getNamebyid(int id) throws IOException {
        //通过id获得name
        String str=null;
        String filePath="D://dns.xls";
        InputStream input = new FileInputStream(filePath);
        Workbook wb = null;
        wb = new HSSFWorkbook(input);
        //得到一个工作表对象;
        Sheet sheet = wb.getSheetAt(0);
        int rsRows = sheet.getLastRowNum();// 获取sheet表中的总行数            
         // 遍历行

        for (int i=0;i<=rsRows;i++) {
            int flag=0;
            String name=null;
            Row row = sheet.getRow(i);
            //遍历行单元格
            Cell cell1= row.getCell(0);
            Cell cell2 = row.getCell(1);
            if(cell1==null||cell1.equals(null)||cell1.getCellType()==CellType.BLANK){
                break;
            }else {
                //数值型
                flag=(int) cell1.getNumericCellValue();
                
            }
            if(cell2==null||cell2.equals(null)||cell2.getCellType()==CellType.BLANK){
                 break;
            }else {
                //字符串型
                name= cell2.getStringCellValue();
            }
            if(flag==id){
                str=name;
            }
        }
        
        wb.close();//记得关闭    
        return str;
}
}
Dao

 

index.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首页</title>
<style >
.a{
        font-size: 26px;
        margin-top: 20px;
    }
</style>
</head>
<body>
<%
         Object message = request.getAttribute("message");
         if(message!=null && !"".equals(message)){
     
%>
     <script type="text/javascript">
              alert("<%=request.getAttribute("message")%>");
         </script>
<%} %>
<div align="center">
        <h1 style="color: red;">公交线路</h1>
        <a href="busServlet?method=list">出示站点信息</a>
        <form action="busServlet?method=getIdbyname" method="post" onsubmit="return check()">
            <div >
                起点<input type="text" id="start" name="start"/>
            </div>
            <div >
                终点<input type="text" id="final" name="final" />
            </div>
            <div >
                <button type="submit" >确定</button>
            </div>
        </form>
    </div>
    <script type="text/javascript">
        function check() {
            var a = document.getElementById("start");
            var b= document.getElementById("final");
            //非空
            if(a.value == '') {
                alert('起点为空');
                a.focus();
                return false;
            }
            if(b.value == '') {
                alert('终点为空');
                b.focus();
                return false;
            }
        }
    </script>
</body>
</html>
index.jsp

list.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>列出表格内容</title>
<style>
    .a{
        margin-top: 20px;
    }
    .b{
        font-size: 20px;
        width: 160px;
        color: white;
        background-color: greenyellow;
    }
    .tb, td {
        border: 1px solid black;
        font-size: 22px;
    }
</style>
</head>
<body>
    <%
         Object message = request.getAttribute("message");
         if(message!=null && !"".equals(message)){
     
    %>
         <script type="text/javascript">
              alert("<%=request.getAttribute("message")%>");
         </script>
    <%} %>
    <div align="center">
        <h1 style="color: red;">站点列表</h1>
        <a href="index.jsp">返回主页</a>
        <table class="tb">
            <tr>
                <td>站点id</td>
                <td>站点名称</td>
            </tr>
            <c:forEach items="${buses}" var="item">
                <tr>
                    <td>${item.id}</td>
                    <td>${item.name}</td>
                </tr>
            </c:forEach>
        </table>
    </div>
</body>
</html>
list.jsp

 succeed.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>最短路径</title>
<style>
    .a{
        margin-top: 20px;
    }
    .b{
        font-size: 20px;
        width: 160px;
        color: white;
        background-color: greenyellow;
    }
    .tb, td {
        border: 1px solid black;
        font-size: 22px;
    }
</style>
</head>
<body>
    <%
         Object message = request.getAttribute("message");
         if(message!=null && !"".equals(message)){
     
    %>
         <script type="text/javascript">
              alert("<%=request.getAttribute("message")%>");
         </script>
    <%} %>
    <div align="center">
        <h1 style="color: red;">最短路径</h1>
        <a href="index.jsp">返回主页</a>
        <table class="tb">
            <tr>
                <td>站点倒序</td>
            </tr>
            <c:forEach items="${stations}" var="item">
                <tr>
                    <td>${item}</td>
                </tr>
            </c:forEach>
        </table>
    </div>
</body>
</html>
succeed.jsp

 

项目布局:(与连接数据库操作基本相同,只不过本人做的时候没有另建类似连接数据库的excelutil包,而是直接在dao层连接;小伙伴们可以尝试建立excelutil包,会方便很多)

 

 

运行截图:

主页:index.jsp

 

点击“出示站点信息”:list.jsp

输入起点,终点:

 检查输入站点名称:

输出最短路径:succeed.jsp

 

posted @ 2019-07-08 00:50  田智凯  阅读(696)  评论(0编辑  收藏  举报