数据结构课程设计---赛事统计,校园导航,算术表达式

本文详细介绍了三个C++编程项目:一是设计一个计算机设计大赛赛事统计系统,包括查看所有学校参赛情况、按学校编号或名称查询等功能;二是实现一个校园导游系统,利用弗洛伊德算法求最短路径;三是实现一个算术表达式求解器,处理中缀表达式转化为后缀表达式并计算结果。每个项目都涉及到数据结构和算法的应用,如数组、链表、栈等,提供了详细的代码实现和测试分析。
摘要由CSDN通过智能技术生成

文章目录

目录

项目一:计算机设计大赛赛事统计

一.内容与相关要求;

问题描述:
参加计算机设计大赛的n个学校编号为1-n,赛事分成m个项目,项目的编号为1~m.比赛获奖
按照得分降序,取前三名,写一个统计程序产生各种成绩单和得分报表。
基本要求:
1)每个比赛项目至少有10支参赛队;每个学校最多有6支队伍参赛;
2)能统计各学校的总分;
3)可以按照学校编号或名称查询,学校的总分、各项目的总分排序输出;
4) 可以按学校编号查询学校某个项目的获奖情况;可以按项目编号查询取得前三名的学校;
5)数据存入文件并能随时查询

二.问题分析和任务定义;

三.数据结构的选择和概要设计;

本题的数据比较繁杂,应该用结构体来处理,Java中的arraylist就默认实现了这个功能,所以这里我选择用list来处理这道题目。

3.1 数据结构的选择

Java-arraylist.

3.2 概要设计

3.2.1 功能函数的设计
Menu()向用户展示菜单函数
CheckAllSchool()查看所有学校参赛情况
CheckProjects()查看某一项目各个小组排名
CheckOneSchool_bianhao()通过编号查看学校参赛情况
CheckOneSchool_Sum(int figure)通过编号查看学校总分
CheckOneSchool_projects(int figure)通过编号查看学校各个项目
CheckOneSchool_name()通过名称查看学校参赛情况
CheckOneSchool_Sum(String string)通过名称查看学校总分
CheckOneSchool_projects(String string)通过名称查看学校各个项目
Award()颁奖函数
AwardQuery_project()查看项目各个小组获奖情况
AwardQuery_school()查看学校获奖情况
ReadTxttoSystem_school()读文档
readTxtFile()查看文件内容
WritetoFile()写入文档
RankSchoool()学校排名

四.详细设计和编码;

4.1 程序流程图

4.2 详细代码

4.2.1Menu() 向用户展示菜单函数
  public static void Menu() {
        System.out.println("欢迎使用赛事统计系统");
        System.out.println(
                "1----查看所有学校参赛情况           2----按照学校名称或编号查询学校参赛情况\n" +
                        "3----查看每个项目的小组排名         4----查看获奖情况\n"+
                        "5----查看文件                     6----将信息写入文件中              \n" +
                        "7----学校排名                     0----退出系统\n");
        System.out.println("请输入您的选择");
    }

4.2.2 CheckAllSchool() 查看所有学校参赛情况
 public static void CheckAllSchool() {
        for (int i = 0; i < arraylist.size(); i++) {
            System.out.println("学校的队伍参赛情况如下:");
            System.out.println("学校 " + arraylist.get(i).name);
            System.out.println("参赛队伍:" + arraylist.get(i).number_of_team + " 支");
            System.out.println("参加项目:" + arraylist.get(i).number_of_project + " 个");
            for (int j = 0; j < arraylist2.size(); j++) {
                if (arraylist2.get(j).name_of_school.equals(arraylist.get(i).name)) {
                    //这支队伍是属于这个学校的
                    System.out.println("编号:" + arraylist2.get(j).bianhao + " 参加的项目是:" + arraylist2.get(j).xiangmubianhao + " 得分" + arraylist2.get(j).score);
                }
            }
            System.out.println("学校 " + arraylist.get(i).name + " 总得分:" + arraylist.get(i).Allscore);
        }
    }
4.2.3 CheckProjects() 查看某一项目各个小组排名
 public static void CheckProjects() {
        Scanner input = new Scanner(System.in);
        boolean flag = true;
        int num = 0;
        while (flag) {
            System.out.println("请输入您想查询的是几号项目?");
            int choice = input.nextInt();
            if (choice < 1 || choice > 6) {
                System.out.println("您的输入有误,是否重新输入? y/n");
                String a = input.next();
                if (a.equals("n")) {
                    flag = false;
                }
            } else {
                flag = false;
            }
            num = choice;
        }
        ArrayList<Team> work = new ArrayList<Team>();
        System.out.println("查询的是" + num);
        for (int i = 0; i < arraylist2.size(); i++) {
            if (arraylist2.get(i).xiangmubianhao == num) {
                work.add(arraylist2.get(i));
            }
        }
        Collections.sort(work, new Comparator<Team>() {
            public int compare(Team o1, Team o2) {
                if (o1.getScore() > o2.getScore()) {
                    return -1;
                }
                if (o1.getScore() < o2.getScore()) {
                    return 0;
                }
                return 1;
            }
        });
        for (int i = 0; i < work.size(); i++) {
            System.out.println("第" + (i + 1) + "名 " + " 第 " + work.get(i).bianhao + " 组" + "  学校:" + work.get(i).name_of_school + " 得分 " + work.get(i).score);
        }
    }
4.2.4 CheckOneSchool_bianhao() 通过编号查看学校参赛情况
 public static void CheckOneSchool_bianhao() {
        Scanner input = new Scanner(System.in);
        ArrayList<Integer> work = new ArrayList<>();
        for (int i = 0; i < arraylist.size(); i++) {
            work.add(arraylist.get(i).bianhao_of_school);
        }
        boolean flag = true;
        int num = 0;
        while (flag) {
            System.out.println("请输入您想查询的学校的编号");
            int a = input.nextInt();
            if (!work.contains(a)) {
                System.out.println("您输入的编号不存在,请重新输入");
            } else {
                num = a;
                flag = false;
            }
        }
        boolean flag3 = true;
        while (flag3) {
            System.out.println("请输入您的选择");
            System.out.println("1----查询学校总分");
            System.out.println("2----查询学校参赛项目情况");
            int a = input.nextInt();
            switch (a) {
                case 1:
                    CheckOneSchool_Sum(num);
                    flag3 = false;
                    break;
                case 2:
                    CheckOneSchool_projects(num);
                    flag3 = false;
                    break;
                default:
                    System.out.println("您的输入有误,请重新输入");
            }
        }
    }
4.2.5 CheckOneSchool_projects(int figure) 通过编号查看学校各个项目
public static void CheckOneSchool_projects(int figure) {
        ArrayList<Integer> work = new ArrayList<Integer>();
        ArrayList<Team> work_list = new ArrayList<Team>();
        String name = "NULL";
        for (int i = 0; i < arraylist.size(); i++) {
            if (arraylist.get(i).bianhao_of_school == figure) {
                name = arraylist.get(i).name;
            }
        }
        for (int i = 0; i < arraylist2.size(); i++) {
            if (arraylist2.get(i).name_of_school.equals(name)) {
                work_list.add(arraylist2.get(i));
            }
            if (!(work.contains(arraylist2.get(i).xiangmubianhao))) {
                work.add(arraylist2.get(i).xiangmubianhao);
            }
        }
        int sum = 0;
        //work中存放的是这个学校参加的所有项目编号
        for (int i = 0; i < work.size(); i++) {
            for (int j = 0; j < work_list.size(); j++) {
                if (work_list.get(j).xiangmubianhao == work.get(i)) {
                    sum += work_list.get(j).score;
                }
            }
            System.out.println("项目编号:" + work.get(i) + " 总得分:" + sum);
            sum = 0;
        }
    }
4.2.6 Award() 颁奖函数
 public static void Award() {
        ArrayList<Team> work_list = new ArrayList<Team>();
        for (int i = 1; i <= xiangmushu; i++) {//对于每个项目
            for (int j = 0; j < arraylist2.size(); j++) {
                if (arraylist2.get(j).xiangmubianhao == i) {
                    work_list.add(arraylist2.get(j));
                }
            }//work_list中是参加了项目i的所有团队的集合
            Collections.sort(work_list, new Comparator<Team>() {
                public int compare(Team o1, Team o2) {
                    if (o1.getScore() > o2.getScore()) {
                        return -1;
                    }
                    if (o1.getScore() < o2.getScore()) {
                        return 0;
                    }
                    return 1;
                }
            });
            work_list.get(0).medal = "金牌";
            work_list.get(1).medal = "银牌";
            work_list.get(2).medal = "铜牌";
            for (int k = 0; k < arraylist2.size(); k++) {
                if (arraylist2.get(k).bianhao == work_list.get(0).bianhao) {
                    arraylist2.get(k).setMedal(work_list.get(0).medal);
                }
                if (arraylist2.get(k).bianhao == work_list.get(1).bianhao) {
                    arraylist2.get(k).setMedal(work_list.get(1).medal);
                }
                if (arraylist2.get(k).bianhao == work_list.get(2).bianhao) {
                    arraylist2.get(k).setMedal(work_list.get(2).medal);
                }
            }
            work_list.clear();
        }
    }
4.2.7 AwardQuery_project() 查看项目各个小组获奖情况
  public static void AwardQuery_project() {
        boolean flag = true;
        int num = 0;
        while (flag) {
            System.out.println("请输入您想查询的项目编号");
            Scanner input = new Scanner(System.in);
            int a = input.nextInt();
            if (a < 1 || a > xiangmushu) {
                System.out.println("您的输入有误,请重新输入");
            } else {
                num = a;
                flag = false;
            }
        }//要查询的是num号程序
        ArrayList<Team> work_list = new ArrayList<Team>();
        for (int i = 0; i < arraylist2.size(); i++) {
            if (arraylist2.get(i).xiangmubianhao == num) {
                work_list.add(arraylist2.get(i));
            }
        }//work_list是参加了num号项目的所有队伍的集合
        for (int i = 0; i < work_list.size(); i++) {
            System.out.println(work_list.get(i).name_of_school);
        }
        Collections.sort(work_list, new Comparator<Team>() {
            public int compare(Team o1, Team o2) {
                if (o1.getScore() > o2.getScore()) {
                    return -1;
                }
                if (o1.getScore() < o2.getScore()) {
                    return 0;
                }
                return 1;
            }
        });
        for (int i = 0; i < work_list.size(); i++) {
            System.out.println(work_list.get(i).name_of_school);
        }
        System.out.println(work_list.size());
        for (int i = 0; i < work_list.size(); i++) {
            System.out.println("第" + (i + 1) + "名" + " 队伍编号:" + work_list.get(i).bianhao + " 隶属学校:" + work_list.get(i).name_of_school + " 得分:" + work_list.get(i).score + " 奖牌情况: " + work_list.get(i).medal);
        }
    }
4.2.8 ReadTxttoSystem_school() 读文档
 public static void ReadTxttoSystem_school() {
        try {
            String path = "D:\\Statistics of computer design competition\\tt.txt";
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(path)), StandardCharsets.UTF_8));
            String lineTxt = null;
            while ((lineTxt = br.readLine()) != null) {
                School school = new School();
                String[] txt = lineTxt.split(",");
                school.setBianhao_of_school(Integer.parseInt(txt[0]));
                school.setName(txt[1]);
                school.setNumber_of_project(Integer.parseInt(txt[2]));
                school.setNumber_of_team(Integer.parseInt(txt[3]));
                school.setAllscore(Integer.parseInt(txt[4]));
                arraylist.add(school);
            }
            br.close();
        } catch (Exception e) {
            System.out.println("1 = " + e);
        }
    }
4.2.9 RankSchoool() 学校排名
 public static void RankSchool(){
        Collections.sort(arraylist, new Comparator<School>() {
            public int compare(School o1, School o2) {
                if (o1.getAllscore() > o2.getAllscore()) {
                    return -1;
                }
                if (o1.getAllscore() < o2.getAllscore()) {
                    return 0;
                }
                return 1;
            }
        });
        for (int i = 0; i < arraylist.size(); i++) {
            System.out.println("第"+(i+1)+"名 "+arraylist.get(i).name+" 总分:"+arraylist.get(i).Allscore);
        }
    }

4.3 完整代码

package yangchuang;

import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Scanner;
import java.util.ArrayList;
import java.io.*;
import java.util.Comparator;

public class Statistics_of_competition {
    static ArrayList<School> arraylist = new ArrayList<School>();//所有参加比赛的学校的list
    static ArrayList<Team> arraylist2 = new ArrayList<Team>();//所有参加比赛的团队的list
    static int xiangmushu = 0;

    public static void main(String[] args) throws IOException {
       /* for (int i = 0; i < arraylist2.size(); i++) {
            System.out.println(arraylist2.get(i).name_of_school + " " + arraylist2.get(i).score);
        }*/
        Scanner input = new Scanner(System.in);
        System.out.println("请根据您传入的文件,修改项目数,请输入项目数的值");
        int num = input.nextInt();
        xiangmushu = num;
        ReadTxttoSystem_school();
        ReadTxtToSystem_team();
        for (int i = 0; i < arraylist2.size(); i++) {
            System.out.println(arraylist2.get(i).name_of_school + " " + arraylist2.get(i).score);
        }
        while (true) {
            Menu();
            int choice = input.nextInt();
            switch (choice) {
                case 1:
                    CheckAllSchool();
                    break;
                case 2:
                    CheckSchool();
                    break;
                case 3:
                    CheckProjects();
                    break;
                case 4:
                    CheckAward();
                    WritetoFile();
                    break;
                case 5:
                    readTxtFile();
                    break;
                case 6:
                    WritetoFile();
                    break;
                case 7:
                    RankSchool();
                    break;
                case 0:
                    System.out.println("感谢您的使用");
                    System.exit(0);
            }
        }
    }

    public static void Menu() {
        System.out.println("欢迎使用赛事统计系统");
        System.out.println(
                "1----查看所有学校参赛情况           2----按照学校名称或编号查询学校参赛情况\n" +
                        "3----查看每个项目的小组排名         4----查看获奖情况\n" +
                        "5----查看文件                     6----将信息写入文件中              \n" +
                        "7----学校排名                     0----退出系统\n");
        System.out.println("请输入您的选择");
    }

    public static void CheckAllSchool() {
        for (int i = 0; i < arraylist.size(); i++) {
            System.out.println("学校的队伍参赛情况如下:");
            System.out.println("学校 " + arraylist.get(i).name);
            System.out.println("参赛队伍:" + arraylist.get(i).number_of_team + " 支");
            System.out.println("参加项目:" + arraylist.get(i).number_of_project + " 个");
            for (int j = 0; j < arraylist2.size(); j++) {
                if (arraylist2.get(j).name_of_school.equals(arraylist.get(i).name)) {
                    //这支队伍是属于这个学校的
                    System.out.println("编号:" + arraylist2.get(j).bianhao + " 参加的项目是:" + arraylist2.get(j).xiangmubianhao + " 得分" + arraylist2.get(j).score);
                }
            }
            System.out.println("学校 " + arraylist.get(i).name + " 总得分:" + arraylist.get(i).Allscore);
        }
    }

    public static void CheckProjects() {
        Scanner input = new Scanner(System.in);
        boolean flag = true;
        int num = 0;
        while (flag) {
            System.out.println("请输入您想查询的是几号项目?");
            int choice = input.nextInt();
            if (choice < 1 || choice > 6) {
                System.out.println("您的输入有误,是否重新输入? y/n");
                String a = input.next();
                if (a.equals("n")) {
                    flag = false;
                }
            } else {
                flag = false;
            }
            num = choice;
        }
        ArrayList<Team> work = new ArrayList<Team>();
        System.out.println("查询的是" + num);
        for (int i = 0; i < arraylist2.size(); i++) {
            if (arraylist2.get(i).xiangmubianhao == num) {
                work.add(arraylist2.get(i));
            }
        }
        Collections.sort(work, new Comparator<Team>() {
            public int compare(Team o1, Team o2) {
                if (o1.getScore() > o2.getScore()) {
                    return -1;
                }
                if (o1.getScore() < o2.getScore()) {
                    return 0;
                }
                return 1;
            }
        });
        for (int i = 0; i < work.size(); i++) {
            System.out.println("第" + (i + 1) + "名 " + " 第 " + work.get(i).bianhao + " 组" + "  学校:" + work.get(i).name_of_school + " 得分 " + work.get(i).score);
        }
    }

    public static void CheckSchool() {
        Scanner input = new Scanner(System.in);
        boolean flag = true;
        int choice = 0;
        while (flag) {
            System.out.println("1---通过编号查询学校参赛情况");
            System.out.println("2---通过名称查询学校参赛情况");
            System.out.println("请输入您的选择");
            int a = input.nextInt();
            switch (a) {
                case 1:
                    CheckOneSchool_bianhao();
                    flag = false;
                    break;
                case 2:
                    CheckOneSchool_name();
                    flag = false;
                    break;
                default:
                    System.out.println("您的输入有误,请重新输入");
            }
        }
    }

    public static void CheckOneSchool_bianhao() {
        Scanner input = new Scanner(System.in);
        ArrayList<Integer> work = new ArrayList<>();
        for (int i = 0; i < arraylist.size(); i++) {
            work.add(arraylist.get(i).bianhao_of_school);
        }
        boolean flag = true;
        int num = 0;
        while (flag) {
            System.out.println("请输入您想查询的学校的编号");
            int a = input.nextInt();
            if (!work.contains(a)) {
                System.out.println("您输入的编号不存在,请重新输入");
            } else {
                num = a;
                flag = false;
            }
        }
        boolean flag3 = true;
        while (flag3) {
            System.out.println("请输入您的选择");
            System.out.println("1----查询学校总分");
            System.out.println("2----查询学校参赛项目情况");
            int a = input.nextInt();
            switch (a) {
                case 1:
                    CheckOneSchool_Sum(num);
                    flag3 = false;
                    break;
                case 2:
                    CheckOneSchool_projects(num);
                    flag3 = false;
                    break;
                default:
                    System.out.println("您的输入有误,请重新输入");
            }
        }
    }

    public static void CheckOneSchool_Sum(int figure) {
        for (int i = 0; i < arraylist.size(); i++) {
            if (arraylist.get(i).bianhao_of_school == figure) {
                System.out.println("学校:" + arraylist.get(i).name + " 总得分为:" + arraylist.get(i).Allscore);
            }
        }
    }

    public static void CheckOneSchool_projects(int figure) {
        ArrayList<Integer> work = new ArrayList<Integer>();
        ArrayList<Team> work_list = new ArrayList<Team>();
        String name = "NULL";
        for (int i = 0; i < arraylist.size(); i++) {
            if (arraylist.get(i).bianhao_of_school == figure) {
                name = arraylist.get(i).name;
            }
        }
        for (int i = 0; i < arraylist2.size(); i++) {
            if (arraylist2.get(i).name_of_school.equals(name)) {
                work_list.add(arraylist2.get(i));
            }
            if (!(work.contains(arraylist2.get(i).xiangmubianhao))) {
                work.add(arraylist2.get(i).xiangmubianhao);
            }
        }
        int sum = 0;
        //work中存放的是这个学校参加的所有项目编号
        for (int i = 0; i < work.size(); i++) {
            for (int j = 0; j < work_list.size(); j++) {
                if (work_list.get(j).xiangmubianhao == work.get(i)) {
                    sum += work_list.get(j).score;
                }
            }
            System.out.println("项目编号:" + work.get(i) + " 总得分:" + sum);
            sum = 0;
        }
    }

    public static void CheckOneSchool_name() {
        Scanner input = new Scanner(System.in);
        ArrayList<String> work_list = new ArrayList<>();
        for (int i = 0; i < arraylist.size(); i++) {
            work_list.add(arraylist.get(i).name);
        }
        boolean flag = true;
        String name = "NULL";
        while (flag) {
            System.out.println("请输入您要查询的学校名称");
            String name_work = input.next();
            if (!work_list.contains(name_work)) {
                System.out.println("您输入的学校不存在,请检查是否输入错误,并重新输入");
            } else {
                name = name_work;
                flag = false;
            }
        }
        boolean flag3 = true;
        while (flag3) {
            System.out.println("请输入您的选择");
            System.out.println("1----查询学校总分");
            System.out.println("2----查询学校参赛项目情况");
            int a = input.nextInt();
            switch (a) {
                case 1:
                    CheckOneSchool_Sum(name);
                    flag3 = false;
                    break;
                case 2:
                    CheckOneSchool_projects(name);
                    flag3 = false;
                    break;
                default:
                    System.out.println("您的输入有误,请重新输入");
            }
        }
    }

    public static void CheckOneSchool_Sum(String string) {
        for (int i = 0; i < arraylist.size(); i++) {
            if (arraylist.get(i).name.equals(string)) {
                System.out.println("学校:" + string + " 总得分为:" + arraylist.get(i).Allscore);
            }
        }
    }

    public static void CheckOneSchool_projects(String string) {
        ArrayList<Integer> work = new ArrayList<Integer>();
        ArrayList<Team> work_list = new ArrayList<Team>();
        for (int i = 0; i < arraylist2.size(); i++) {
            if (arraylist2.get(i).name_of_school.equals(string)) {
                work_list.add(arraylist2.get(i));
            }
            if (!(work.contains(arraylist2.get(i).xiangmubianhao))) {
                work.add(arraylist2.get(i).xiangmubianhao);
            }
        }
        int sum = 0;
        //work中存放的是这个学校参加的所有项目编号
        for (int i = 0; i < work.size(); i++) {
            for (int j = 0; j < work_list.size(); j++) {
                if (work_list.get(j).xiangmubianhao == work.get(i)) {
                    sum += work_list.get(j).score;
                }
            }
            System.out.println("项目编号:" + work.get(i) + " 总得分:" + sum);
            sum = 0;
        }
    }

    public static void Award() {
        ArrayList<Team> work_list = new ArrayList<Team>();
        for (int i = 1; i <= xiangmushu; i++) {//对于每个项目
            for (int j = 0; j < arraylist2.size(); j++) {
                if (arraylist2.get(j).xiangmubianhao == i) {
                    work_list.add(arraylist2.get(j));
                }
            }//work_list中是参加了项目i的所有团队的集合
            Collections.sort(work_list, new Comparator<Team>() {
                public int compare(Team o1, Team o2) {
                    if (o1.getScore() > o2.getScore()) {
                        return -1;
                    }
                    if (o1.getScore() < o2.getScore()) {
                        return 0;
                    }
                    return 1;
                }
            });
            work_list.get(0).medal = "金牌";
            work_list.get(1).medal = "银牌";
            work_list.get(2).medal = "铜牌";
            for (int k = 0; k < arraylist2.size(); k++) {
                if (arraylist2.get(k).bianhao == work_list.get(0).bianhao) {
                    arraylist2.get(k).setMedal(work_list.get(0).medal);
                }
                if (arraylist2.get(k).bianhao == work_list.get(1).bianhao) {
                    arraylist2.get(k).setMedal(work_list.get(1).medal);
                }
                if (arraylist2.get(k).bianhao == work_list.get(2).bianhao) {
                    arraylist2.get(k).setMedal(work_list.get(2).medal);
                }
            }
            work_list.clear();
        }
    }

    public static void CheckAward() {
        Award();
        System.out.println("1---查询某个项目的获奖情况");
        System.out.println("2---查询某个学校的获奖情况");
        System.out.println("请输入您的选择");
        Scanner input = new Scanner(System.in);
        int a = input.nextInt();
        boolean flag = true;
        while (flag) {
            switch (a) {
                case 1:
                    AwardQuery_project();
                    flag = false;
                    break;
                case 2:
                    AwardQuery_school();
                    flag = false;
                    break;
                default:
                    System.out.println("您的输入有误,请重新输入");
            }
        }
    }

    public static void AwardQuery_project() {
        boolean flag = true;
        int num = 0;
        while (flag) {
            System.out.println("请输入您想查询的项目编号");
            Scanner input = new Scanner(System.in);
            int a = input.nextInt();
            if (a < 1 || a > xiangmushu) {
                System.out.println("您的输入有误,请重新输入");
            } else {
                num = a;
                flag = false;
            }
        }//要查询的是num号程序
        ArrayList<Team> work_list = new ArrayList<Team>();
        for (int i = 0; i < arraylist2.size(); i++) {
            if (arraylist2.get(i).xiangmubianhao == num) {
                work_list.add(arraylist2.get(i));
            }
        }//work_list是参加了num号项目的所有队伍的集合
        for (int i = 0; i < work_list.size(); i++) {
            System.out.println(work_list.get(i).name_of_school);
        }
        Collections.sort(work_list, new Comparator<Team>() {
            public int compare(Team o1, Team o2) {
                if (o1.getScore() > o2.getScore()) {
                    return -1;
                }
                if (o1.getScore() < o2.getScore()) {
                    return 0;
                }
                return 1;
            }
        });
        for (int i = 0; i < work_list.size(); i++) {
            System.out.println(work_list.get(i).name_of_school);
        }
        System.out.println(work_list.size());
        for (int i = 0; i < work_list.size(); i++) {
            System.out.println("第" + (i + 1) + "名" + " 队伍编号:" + work_list.get(i).bianhao + " 隶属学校:" + work_list.get(i).name_of_school + " 得分:" + work_list.get(i).score + " 奖牌情况: " + work_list.get(i).medal);
        }
    }

    public static void AwardQuery_school() {
        boolean flag = true;
        String name = "NULL";
        ArrayList<String> work_list = new ArrayList<>();
        for (int i = 0; i < arraylist.size(); i++) {
            work_list.add(arraylist.get(i).name);
        }
        while (flag) {
            System.out.println("请输入您要查询的学校名称");
            Scanner input = new Scanner(System.in);
            String name_work = input.next();
            if (!work_list.contains(name_work)) {
                System.out.println("您输入的学校不存在,请检查是否输入错误,并重新输入");
            } else {
                name = name_work;
                flag = false;
            }
        }//name是你要查询的学校的名称
        ArrayList<Team> worklist = new ArrayList<Team>();
        System.out.println("学校 " + name + " 的获奖情况如下:");
        for (int i = 0; i < arraylist2.size(); i++) {
            if (arraylist2.get(i).name_of_school.equals(name)) {
                System.out.println("队伍编号:" + arraylist2.get(i).bianhao + " 参加的项目:" + arraylist2.get(i).xiangmubianhao + " 得分:" + arraylist2.get(i).score + " " + arraylist2.get(i).medal);
            }
        }
    }
    
    public static void ReadTxttoSystem_school() {
        try {
            String path = "D:\\Statistics of computer design competition\\tt.txt";
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(path)), StandardCharsets.UTF_8));
            String lineTxt = null;
            while ((lineTxt = br.readLine()) != null) {
                School school = new School();
                String[] txt = lineTxt.split(",");
                school.setBianhao_of_school(Integer.parseInt(txt[0]));
                school.setName(txt[1]);
                school.setNumber_of_project(Integer.parseInt(txt[2]));
                school.setNumber_of_team(Integer.parseInt(txt[3]));
                school.setAllscore(Integer.parseInt(txt[4]));
                arraylist.add(school);
            }
            br.close();
        } catch (Exception e) {
            System.out.println("1 = " + e);
        }
    }

    public static void ReadTxtToSystem_team() {
        try {
            String path = "D:\\Statistics of computer design competition\\xx.txt";
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(path)), StandardCharsets.UTF_8));
            String lineTxt = null;
            while ((lineTxt = br.readLine()) != null) {
                Team team = new Team();
                String[] names = lineTxt.split(",");
                team.setName_of_school(names[0]);
                team.setBianhao(Integer.parseInt(names[1]));
                team.setXiangmubianhao(Integer.parseInt(names[2]));
                team.setScore(Integer.parseInt(names[3]));
                team.setMedal(names[4]);
                arraylist2.add(team);
            }
            br.close();
        } catch (Exception e) {
            System.out.println("2 = " + e);
        }
    }

    public static void readTxtFile() throws IOException {
        WritetoFile();
        System.out.println("文件内容如下:");
        String filePath = "D:\\Statistics of computer design competition\\xx.txt";
        try {
            String encoding = "GBK";
            File file = new File(filePath);
            if (file.isFile() && file.exists()) { //判断文件是否存在
                //InputStreamReader read = new InputStreamReader(
                //  new FileInputStream(file),encoding);//考虑到编码格式
                InputStreamReader read = new InputStreamReader(new FileInputStream(file), "utf-8");
                BufferedReader bufferedReader = new BufferedReader(read);
                String lineTxt = null;
                while ((lineTxt = bufferedReader.readLine()) != null) {
                    System.out.println(lineTxt);
                }
                read.close();
            } else {
                System.out.println("找不到指定的文件");
            }
        } catch (Exception e) {
            System.out.println("读取文件内容出错");
            e.printStackTrace();
        }

    }
    
    public static void WritetoFile() throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\Statistics of computer design competition\\xx.txt"));
        for (Team team : arraylist2) {
            StringBuilder sb = new StringBuilder();
            sb.append(team.getName_of_school()).append(",").append(team.getBianhao()).append(",").append(team.getXiangmubianhao()).append(",").append(team.getScore()).append(",").append(team.getMedal()).append(",");
            bw.write(sb.toString());
            bw.newLine();
            bw.flush();
        }
        bw.close();
        System.out.println("写入成功");
    }

    public static void RankSchool() {
        Collections.sort(arraylist, new Comparator<School>() {
            public int compare(School o1, School o2) {
                if (o1.getAllscore() > o2.getAllscore()) {
                    return -1;
                }
                if (o1.getAllscore() < o2.getAllscore()) {
                    return 0;
                }
                return 1;
            }
        });
        for (int i = 0; i < arraylist.size(); i++) {
            System.out.println("第" + (i + 1) + "名 " + arraylist.get(i).name + " 总分:" + arraylist.get(i).Allscore);
        }
    }
}

五.测试结果及其分析;

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这道题目不是很难,但是比较繁杂,我所写的java代码,各个方法的功能比较单一,又加了几个引导方法,所以代码量看上去很多,但是大部分都不难。在做这个题目的过程中,遇到了难点是:不知道怎么把系统中的文件读入java中,不知道如何设置格式。在读入的过程中也遇到了一系列问题,在这里感谢我的Java老师潘老师的细心解答

六.用户使用说明;

七.参考文献;

[1]陈雷,尚冰,杨光等教师教学档案信息管理系统的设计研究.辽宁中医学院学报(第五卷第4期),
2003年11月.
[2]滕佳东.管理信息系统.东北财经高校出版社.2008.2.
[3]甘仞初,颜志军,龙虹信息系统分析与设计.北京:高等教育出版社,2003.
[4]刘永勤.成人高校教学档案开发利用的现实意义中文期刊.2008年3期.
[5]张海藩.软件工程导论(第五版)学习辅导.清华高校出版社,2008年9期.

附录;

项目二:校园导游系统

一.内容与相关要求

1.内容:设计一个校园导游程序,为来访的客人提供各种信息查询服务。
2.相关要求:
(1) 设计你所在学校的校园平面图,所含景点不少于10个.以图中顶点表示校内各景点,存放景点名称、代号、简介 等信息;以边表示路径,存放路径长度等相关信息。
(2) 为来访客人提供图中任意景点相关信息的查询。
(3) 为来访客人提供图中任意景点的问路查询,即查询任意两个景点之间的一条最短的简单路径。

二.问题分析和任务定义

这个问题实际上是对数据结构中的图的实际应用,由于实际校园中的路都是双向的,故此处为无向图,校园中的景点等效于图中的节点,图中的边表示景点之间的路径,查询任意两个景点之间的一条最短的简单路径,实际为寻找无向图中两个节点之间的最短路径,我们可以使用Dijkstra算法和Floyd-Warshall算法。(这里我选择Floyd方法)。其他重要的函数及其功能会在第四点中详细介绍,这里只讲思想。

三.数据结构的选择和概要设计

3.1 数据结构的选择

校园导游系统,选择数据结构里的图的结构来解决;

3.2 概要设计

3.2.1 总体设计

这里选择江苏科技大学长山校区的13个景点,他们的对应关系为:
江苏科技大学长山校区云图
图片为根据长山校区提取出来的,存在一定误差

1行政楼
2计算机学院楼
3图书馆
4文理大楼
5东苑食堂
6明德楼
7西操场
8文体中心
9东操场
10笃学楼
11西苑食堂
1248栋学生宿舍
13校医院
3.2.2 功能函数的设计

函数一览:

InitGraph()图的初始化函数:
MapDisplay()显示地图函数
Menu()向用户显示菜单函数
PrintAllInfo()打印所有景点信息函数
Floyd()弗洛伊德函数求最短路径
ShortestPathOfAnyTwo(MGraph &G)求任意两个景点之间的最短路径函数
DelArc(MGraph &G)删除路径函数
DelVertexMGraph &G)删除景点函数
AddArc(MGraph &G)增加路径函数
UpdateIifo(MGraph &G)更新景点信息函数
PrintAdj(MGraph& G)打印邻接矩阵函数
Prim(MGraph &G)打印邻接矩阵函数

功能一览:

欢迎界面,向用户显示菜单
显示云图和简化图
输出学校景点的基本信息
删除某个景点
增加某条道路
删除某条道路
退出系统
查询任意两景点间的最短路径
查询从某个景点开始最短路程游历完所有景点
在这里插入图片描述

四.详细设计和编码

4.1 程序流程图

4.2 详细代码

4.2.1 结构体定义

结点的结构体定义:

#define MAXVEX 13     //最大顶点个数 
#define INFINITY 3276//图的矩阵中A(i,i)记为0,若没有通路,记为INFINITY = 32762
int PathMatirx[MAXVEX][MAXVEX];
int ShortPath[MAXVEX][MAXVEX];

//结点的结构体--代表实际中的景点
typedef struct {
	int Num;//景点的编号
	string name;       //校园景点名
	string info;    //校园景点的描述信息
}VextexType;

图的结构体定义:

typedef struct {
	int AdjMatrix[MAXVEX][MAXVEX]; //用二维数组来存放邻接矩阵 
	VextexType vex[MAXVEX];    //存放顶点信息
	int vexnum;		//顶点数 
	int arcnum;     //边数 
}MGraph;

弗洛伊德算法简介

弗洛伊德算法
基本思想:
弗洛伊德算法定义了两个二维矩阵:
矩阵D记录顶点间的最小路径
例如D[0][3]= 10,说明顶点03 的最短路径为10;
矩阵P记录顶点间最小路径中的中转点
例如P[0][3]= 1 说明,03的最短路径轨迹为:0 -> 1 -> 3。
它通过3重循环,k为中转点,v为起点,w为终点,循环比较D[v][w]D[v][k] + D[k][w] 最小值,如果D[v][k] + D[k][w] 为更小值,则把D[v][k] + D[k][w] 覆盖保存在D[v][w]中。

在这里插入图片描述

4.2.2 InitGraph() 图的初始化函数:
void InitGraph(MGraph &G) {
	int i = 0, j = 0;
	G.vexnum = 13;
	G.arcnum = 19;
	for (int i = 0; i < 13; i++) {
		G.vex[i].Num = i+1;//第1号景点到第13号景点
	}
	G.vex[0].name = "行政楼";
	G.vex[0].name,"行政楼";
	G.vex[0].info="老师办公,校领导开会的地方";
	G.vex[1].name= "计算机学院楼";
	G.vex[1].info= "有很多需要用到的计算机实验室";
	G.vex[2].name= "图书馆";
	G.vex[2].info= "学习的地方";
	G.vex[3].name= "文理大楼";
	G.vex[3].info= "江科大地标建筑";
	G.vex[4].name= "东苑食堂";
	G.vex[4].info= "菜肴很多,三楼有小龙虾";
	G.vex[5].name= "明德楼";
	G.vex[5].info= "很适合自习,靠经操场,学累了可以去放松一下";
	G.vex[6].name= "西操场";
	G.vex[6].info= "锻炼身体的好地方";
	G.vex[7].name= "文体中心";
	G.vex[7].info= "有羽毛球场,篮球场,乒乓球场等等,在这里可以尽情释放自己,挥洒汗水";
	G.vex[8].name= "东操场";
	G.vex[8].info= "适合傍晚散步,看夕阳,野营等等";
	G.vex[9].name= "笃学楼";
	G.vex[9].info= "楼如其名,笃学明德,经世致用";
	G.vex[10].name= "西苑食堂";
	G.vex[10].info= "三楼有少数民族餐厅,一楼二楼的饭菜都很好吃";
	G.vex[11].name= "48栋学生宿舍";
	G.vex[11].info= "学生晚上休息睡觉的地方";
	G.vex[12].name= "校医院";
	G.vex[12].info= "如果你感觉到身体不适,请来这里";
	//注意无向图是对称的
	for (int i = 0; i < 13; i++) {
		for (int j = 0; j < 13; j++) {
			G.AdjMatrix[i][j] = INFINITY;
			G.AdjMatrix[0][1] = G.AdjMatrix[1][0] = 10;
			G.AdjMatrix[0][2] = G.AdjMatrix[2][0] = 20;
			G.AdjMatrix[1][3] = G.AdjMatrix[3][1] = 5;
			G.AdjMatrix[1][9] = G.AdjMatrix[9][1] = 13;
			G.AdjMatrix[2][9] = G.AdjMatrix[9][2] = 6;
			G.AdjMatrix[2][4] = G.AdjMatrix[4][2] = 8;
			G.AdjMatrix[3][5] = G.AdjMatrix[5][3] = 7;
			G.AdjMatrix[3][9] = G.AdjMatrix[9][3] = 10;
			G.AdjMatrix[4][9] = G.AdjMatrix[9][4] = 8;
			G.AdjMatrix[4][8] = G.AdjMatrix[8][4] = 12;
			G.AdjMatrix[5][6] = G.AdjMatrix[6][5] = 5;
			G.AdjMatrix[5][10] = G.AdjMatrix[10][5] = 10;
			G.AdjMatrix[6][10] = G.AdjMatrix[10][6] = 10;
			G.AdjMatrix[6][7] = G.AdjMatrix[7][6] = 8;
			G.AdjMatrix[6][12] = G.AdjMatrix[12][6] = 15;
			G.AdjMatrix[7][9] = G.AdjMatrix[9][7] = 15;
			G.AdjMatrix[7][12] = G.AdjMatrix[12][7] = 20;
			G.AdjMatrix[8][9] = G.AdjMatrix[9][8] = 15;
			G.AdjMatrix[10][11] = G.AdjMatrix[11][10] = 7;
			G.AdjMatrix[10][12] = G.AdjMatrix[12][10] = 15;
			G.AdjMatrix[11][12] = G.AdjMatrix[12][11] = 17;
		}
	}
}
4.2.3 MapDisplay() 显示地图函数

在此之前,我已经把需要用到的照片放到和代码相同的文件夹下,调用system函数,使用Windows自带的几何画板来打开图片
在这里插入图片描述

void MapDisplay() {
	system("mspaint Cloud_Picture.jpg");//使用Windows自带的画板打开校园云图
	system("mspaint Plane_Figure.png");//使用Windows自带的画板打开校园平面图
}
4.2.4 Menu() 向用户显示菜单函数
void Menu() {
	system("cls");//清屏
	cout << endl;
	cout << "|----------------------------欢迎来到江苏科技大学-------------------------------\n";
	cout << "|---------------------------校园导游系统功能菜单图------------------------------\n";
	cout << "|*******************************************************************************\n";
	cout << "|      1.显示江苏科技大学云图和景点平面图     2. 校园景点一览                   \n";
	cout << "|      3.显示任意两个景点间的最短路径         4. 增加某个景点                   \n";
	cout << "|      5.删除某个景点                         6.增加某条道路                    \n";
	cout << "|      7.删除某条道路                         8.更新景点信息                    \n";
	cout << "|      9.查看邻接矩阵                         10.查询从某个景点开始最短路程游历完所有景点 \n";
	cout << "|      0.退出                                                                   \n";
	cout << "|*******************************************************************************\n";
	cout << endl;
}
4.2.5 PrintAllInfo() 打印所有景点信息函数
void PrintAllInfo(MGraph &G) {
	cout.setf(ios::left, ios::adjustfield);
	cout << setw(10) << "编号" << setw(15) << "名称" << "简介" << endl;
	for (int i = 0; i < G.vexnum; i++){
		cout << setw(10) << G.vex[i].Num << setw(15) << G.vex[i].name << G.vex[i].info << endl;
	}
}
4.2.6 Floyd() 弗洛伊德函数求最短路径
/*
Floyd算法(弗洛伊德算法)求最短路径:
两个准备的二维数组:
int PathMatirx[MAXVEX][MAXVEX];//记录对应点的最小路径的前驱点,例如p(1,3) = 2 说明顶点1到顶点3的最小路径要经过2
int ShortPath[MAXVEX][MAXVEX];//记录顶点间的最小路径值
*/
void Floyd(MGraph &G){
	//对Floyd的两个数组进行初始化
	for (int i = 0; i < G.vexnum; i++) {
		for (int j = 0; j < G.vexnum; j++) {
			PathMatirx[i][j] = j;
			ShortPath[i][j] = G.AdjMatrix[i][j];
		}
	}
	for (int k = 0; k < G.vexnum; k++) {
		for (int v = 0; v < G.vexnum; v++) {
			for (int w = 0; w < G.vexnum; w++) {
				if (ShortPath[v][w] > ShortPath[v][k] + ShortPath[k][w]) {
					//更新最短路径
					ShortPath[v][w] = ShortPath[v][k] + ShortPath[k][w];
					//更新路径中介节点
					PathMatirx[v][w] = PathMatirx[v][k];
				}
			}
		}
	}
}
4.2.7 ShortestPathOfAnyTwo(MGraph &G)

求任意两个景点之间的最短路径函数

void ShortestPathOfAnyTwo(MGraph &G){
	int start, end, k;
	bool flag1 = false;
	bool flag2 = false;
	cout << "请您输入要查询最短路径的两个不同的景点的编号!" << endl;
	cout << "请您输入起点景点的编号:";
	cin >> start;
	cout << "请您输入终点景点的编号:";
	cin >> end;
	if (start==end){
	cout << "对不起!您所输入的两个景点的编号一样,请重新输入" << endl;
	}
	for (int i = 0; i < G.vexnum; i++){
		if (start == G.vex[i].Num){
			flag1 = true;
		}
		if (end == G.vex[i].Num){ 
			flag2 = true;
		}
	}
	if (!(flag1 == true && flag2 == true)) {
		cout << "您输入的两个景点中有不存在的情况,请重新输入" << endl;
	}
	cout << "从景点 " << G.vex[start-1].name << " 到景点 " << G.vex[end-1].name << "的最短路径长度为:" << ShortPath[start][end] << endl;
	cout << "具体路径为:" << endl;
	k = PathMatirx[start][end];
	cout << start << "--->";
	while (k != end) {
		cout << k << "--->";
		k = PathMatirx[k][end];
	}
	cout << end << endl;
}
4.2.8 DelArc(MGraph &G) 删除路径函数
void DelArc(MGraph &G) {
	int start;
	int end;//start和end都是从1开始
	cout << "请输入您想删除的边的起始结点" << endl;
	cin >> start;
	if (start < 1 || start>G.vexnum) {
		cout << "您输入的结点不存在" << endl;
		return;
	}
	cout << "请输入您想删除的边的结束结点" << endl;
	cin >> end;
	if (end < 1 || end>G.vexnum) {
		cout << "您输入的结点不存在" << endl;
		return;
	}
	if (start == end) {
		cout << "当前输入的两个节点相同" << endl;
		return;
	}
	if (G.AdjMatrix[start-1][end-1] == INFINITY) {
		cout << G.AdjMatrix[start - 1][end - 1] << endl;
		cout << "当前两节点之间无边" << endl;
		return;
	}
	G.AdjMatrix[start-1][end-1] = G.AdjMatrix[end-1][start-1] = INFINITY;
	G.arcnum--;
	cout << "删除成功" << endl;
}
4.2.9 DelVertexMGraph &G) 删除景点函数
void DelVertex(MGraph &G) {
	int number;
	cout << "请输入您想删去的结点的编号" <<endl;
	cin >> number;
	if (number<1 || number>G.vexnum) {
		cout << "您的输入有误,请重新输入" << endl;
	}
	int count = 0;
	//删去顶点v和所有与之关联的边
	for (int i = 0; i < G.vexnum; i++) {
		if (!(G.AdjMatrix[i][number-1] == INFINITY)) {
			G.AdjMatrix[i][number - 1] = G.AdjMatrix[number - 1][i] = INFINITY;
			count++;
		}
	}
	G.vex[number - 1].name = "NULL";
	G.vex[number - 1].info = "NULL";
	PrintAllInfo(G);
}
4.2.10 AddArc(MGraph &G) 增加路径函数
void AddArc(MGraph &G) {
	int start;
	int end;//start和end都是从1开始
	cout << "请输入您想增加的边的起始结点" << endl;
	cin >> start;
	if (start < 1 || start>G.vexnum) {
		cout << "您输入的结点不存在" << endl;
		return;
	}
	cout << "请输入您想增加的边的结束结点" << endl;
	cin >> end;
	if (end < 1 || end > G.vexnum) {
		cout << "您输入的结点不存在" << endl;
		return;
	}
	if (start == end) {
		cout << "当前输入的两个节点相同" << endl;
		return;
	}
	if (!(G.AdjMatrix[start-1][end-1] == INFINITY)) {
		cout << "当前两节点之间已有边" << endl;
		return;
	}
	int weight;
	cout << "请输入您想增加的边的权重" << endl;
	cin >> weight;
	G.AdjMatrix[start-1][end-1] = G.AdjMatrix[end-1][start-1] = weight;
	cout << "增加成功" << endl;
	G.arcnum++;
}
4.2.11 UpdateIifo(MGraph &G) 更新景点信息函数
void UpdateIifo(MGraph &G) {
	//更新景点信息
	int number;
	string info;
	string name;
	cout << "请输入您想更新的景点的编号" << endl;
	cin >> number;
	if (number<1 || number>G.vexnum) {
		cout << "您的输入有误,请重新输入" << endl;
		return;
	}
	cout << "请输入景点新的信息" << endl;
	cin >> info;
	cout << info << endl;
	G.vex[number - 1].info = info;
	cin >> name;
	cout << name << endl;
	G.vex[number - 1].name = name;
	cout << "修改成功" << endl;
	PrintAllInfo(G);
}
4.2.12 PrintAdj(MGraph& G) 打印邻接矩阵函数
void PrintAdj(MGraph& G) {
	for (int i = 0; i < G.vexnum; i++) {
		for (int j = 0; j < G.vexnum; j++) {
			cout << G.AdjMatrix[i][j] << " ";
		}
		cout << endl;
	}
}
4.2.13 void Prim(MGraph &G)

4.3 完整代码

#include <stdio.h>
#include <windows.h>
#include<iostream>//setw
#include <iomanip>//cout
#include<fstream>  //使用输入文件流ifstream
#include <string.h>//在使用字符数组的时候需要用到
#include <stdlib.h>//包含system等系统调用
#include <conio.h>//定义了通过键盘产生的对应的操作
using namespace std;

#define MAXVEX 13     //最大顶点个数 
#define INFINITY 3276//图的矩阵中A(i,i)记为0,若没有通路,记为INFINITY = 32762
int PathMatirx[MAXVEX][MAXVEX];
int ShortPath[MAXVEX][MAXVEX];

//结点的结构体--代表实际中的景点
typedef struct {
	int Num;//景点的编号
	string name;       //校园景点名
	string info;    //校园景点的描述信息
}VextexType;

//邻接矩阵的数据类型 
typedef struct {
	int AdjMatrix[MAXVEX][MAXVEX]; //用二维数组来存放邻接矩阵 
	VextexType vex[MAXVEX];    //存放顶点信息
	int vexnum;		//顶点数 
	int arcnum;     //边数 
}MGraph;


/*
主要函数及其功能介绍
void InitGraph();//初始化无向图
void Menu();//向用户显示菜单
void PrintAllInfo();//打印所有景点的信息
void MapDisplay();//显示地图函数
void ShortestPathOfAnyTwo(MGraph G);//查询任意两景点之间最短路径
void Floyd();//弗洛伊德算法求最短路径函数
void AddArc(MGraph G);//增加边<v,w>
DelVertex(MGraph G);//删去顶点v和所有与之关联的边
DelArc(MGraph G);//删去边<v,w>
UpdateIifo();//更新景点信息
*/
void InitGraph(MGraph &G) {
	int i = 0, j = 0;
	G.vexnum = 13;
	G.arcnum = 19;
	for (int i = 0; i < 13; i++) {
		G.vex[i].Num = i+1;//第1号景点到第13号景点
	}
	G.vex[0].name = "行政楼";
	G.vex[0].name,"行政楼";
	G.vex[0].info="老师办公,校领导开会的地方";
	G.vex[1].name= "计算机学院楼";
	G.vex[1].info= "有很多需要用到的计算机实验室";
	G.vex[2].name= "图书馆";
	G.vex[2].info= "学习的地方";
	G.vex[3].name= "文理大楼";
	G.vex[3].info= "江科大地标建筑";
	G.vex[4].name= "东苑食堂";
	G.vex[4].info= "菜肴很多,三楼有小龙虾";
	G.vex[5].name= "明德楼";
	G.vex[5].info= "很适合自习,靠经操场,学累了可以去放松一下";
	G.vex[6].name= "西操场";
	G.vex[6].info= "锻炼身体的好地方";
	G.vex[7].name= "文体中心";
	G.vex[7].info= "有羽毛球场,篮球场,乒乓球场等等,在这里可以尽情释放自己,挥洒汗水";
	G.vex[8].name= "东操场";
	G.vex[8].info= "适合傍晚散步,看夕阳,野营等等";
	G.vex[9].name= "笃学楼";
	G.vex[9].info= "楼如其名,笃学明德,经世致用";
	G.vex[10].name= "西苑食堂";
	G.vex[10].info= "三楼有少数民族餐厅,一楼二楼的饭菜都很好吃";
	G.vex[11].name= "48栋学生宿舍";
	G.vex[11].info= "学生晚上休息睡觉的地方";
	G.vex[12].name= "校医院";
	G.vex[12].info= "如果你感觉到身体不适,请来这里";
	//注意无向图是对称的
	for (int i = 0; i < 13; i++) {
		for (int j = 0; j < 13; j++) {
			G.AdjMatrix[i][j] = INFINITY;
			G.AdjMatrix[0][1] = G.AdjMatrix[1][0] = 10;
			G.AdjMatrix[0][2] = G.AdjMatrix[2][0] = 20;
			G.AdjMatrix[1][3] = G.AdjMatrix[3][1] = 5;
			G.AdjMatrix[1][9] = G.AdjMatrix[9][1] = 13;
			G.AdjMatrix[2][9] = G.AdjMatrix[9][2] = 6;
			G.AdjMatrix[2][4] = G.AdjMatrix[4][2] = 8;
			G.AdjMatrix[3][5] = G.AdjMatrix[5][3] = 7;
			G.AdjMatrix[3][9] = G.AdjMatrix[9][3] = 10;
			G.AdjMatrix[4][9] = G.AdjMatrix[9][4] = 8;
			G.AdjMatrix[4][8] = G.AdjMatrix[8][4] = 12;
			G.AdjMatrix[5][6] = G.AdjMatrix[6][5] = 5;
			G.AdjMatrix[5][10] = G.AdjMatrix[10][5] = 10;
			G.AdjMatrix[6][10] = G.AdjMatrix[10][6] = 10;
			G.AdjMatrix[6][7] = G.AdjMatrix[7][6] = 8;
			G.AdjMatrix[6][12] = G.AdjMatrix[12][6] = 15;
			G.AdjMatrix[7][9] = G.AdjMatrix[9][7] = 15;
			G.AdjMatrix[7][12] = G.AdjMatrix[12][7] = 20;
			G.AdjMatrix[8][9] = G.AdjMatrix[9][8] = 15;
			G.AdjMatrix[10][11] = G.AdjMatrix[11][10] = 7;
			G.AdjMatrix[10][12] = G.AdjMatrix[12][10] = 15;
			G.AdjMatrix[11][12] = G.AdjMatrix[12][11] = 17;
		}
	}
}

void MapDisplay() {
	system("mspaint Cloud_Picture.jpg");//使用Windows自带的画板打开校园云图
	system("mspaint Plane_Figure.png");//使用Windows自带的画板打开校园平面图
}

void Menu() {
	system("cls");//清屏
	cout << endl;
	cout << "|----------------------------欢迎来到江苏科技大学-------------------------------\n";
	cout << "|---------------------------校园导游系统功能菜单图------------------------------\n";
	cout << "|*******************************************************************************\n";
	cout << "|      1.显示江苏科技大学云图和景点平面图     2. 校园景点一览                   \n";
	cout << "|      3.显示任意两个景点间的最短路径         4. 增加某个景点                   \n";
	cout << "|      5.删除某个景点                         6.增加某条道路                    \n";
	cout << "|      7.删除某条道路                         8.更新景点信息                    \n";
	cout << "|      9.查看邻接矩阵                         10.查询从某个景点开始最短路程游历完所有景点 \n";
	cout << "|      0.退出                                                                   \n";
	cout << "|*******************************************************************************\n";
	cout << endl;
}

void PrintAllInfo(MGraph &G) {
	cout.setf(ios::left, ios::adjustfield);
	cout << setw(10) << "编号" << setw(15) << "名称" << "简介" << endl;
	for (int i = 0; i < G.vexnum; i++){
		cout << setw(10) << G.vex[i].Num << setw(15) << G.vex[i].name << G.vex[i].info << endl;
	}
}


/*
Floyd算法(弗洛伊德算法)求最短路径:
两个准备的二维数组:
int PathMatirx[MAXVEX][MAXVEX];//记录对应点的最小路径的前驱点,例如p(1,3) = 2 说明顶点1到顶点3的最小路径要经过2
int ShortPath[MAXVEX][MAXVEX];//记录顶点间的最小路径值
*/
void Floyd(MGraph &G){
	//对Floyd的两个数组进行初始化
	for (int i = 0; i < G.vexnum; i++) {
		for (int j = 0; j < G.vexnum; j++) {
			PathMatirx[i][j] = j;
			ShortPath[i][j] = G.AdjMatrix[i][j];
		}
	}
	for (int k = 0; k < G.vexnum; k++) {
		for (int v = 0; v < G.vexnum; v++) {
			for (int w = 0; w < G.vexnum; w++) {
				if (ShortPath[v][w] > ShortPath[v][k] + ShortPath[k][w]) {
					//更新最短路径
					ShortPath[v][w] = ShortPath[v][k] + ShortPath[k][w];
					//更新路径中介节点
					PathMatirx[v][w] = PathMatirx[v][k];
				}
			}
		}
	}
}

void ShortestPathOfAnyTwo(MGraph &G){
	int start, end, k;
	bool flag1 = false;
	bool flag2 = false;
	cout << "请您输入要查询最短路径的两个不同的景点的编号!" << endl;
	cout << "请您输入起点景点的编号:";
	cin >> start;
	cout << "请您输入终点景点的编号:";
	cin >> end;
	if (start==end){
	cout << "对不起!您所输入的两个景点的编号一样,请重新输入" << endl;
	}
	for (int i = 0; i < G.vexnum; i++){
		if (start == G.vex[i].Num){
			flag1 = true;
		}
		if (end == G.vex[i].Num){ 
			flag2 = true;
		}
	}
	if (!(flag1 == true && flag2 == true)) {
		cout << "您输入的两个景点中有不存在的情况,请重新输入" << endl;
	}
	cout << "从景点 " << G.vex[start-1].name << " 到景点 " << G.vex[end-1].name << "的最短路径长度为:" << ShortPath[start][end] << endl;
	cout << "具体路径为:" << endl;
	k = PathMatirx[start][end];
	cout << start << "--->";
	while (k != end) {
		cout << k << "--->";
		k = PathMatirx[k][end];
	}
	cout << end << endl;
}


void DelArc(MGraph &G) {
	int start;
	int end;//start和end都是从1开始
	cout << "请输入您想删除的边的起始结点" << endl;
	cin >> start;
	if (start < 1 || start>G.vexnum) {
		cout << "您输入的结点不存在" << endl;
		return;
	}
	cout << "请输入您想删除的边的结束结点" << endl;
	cin >> end;
	if (end < 1 || end>G.vexnum) {
		cout << "您输入的结点不存在" << endl;
		return;
	}
	if (start == end) {
		cout << "当前输入的两个节点相同" << endl;
		return;
	}
	if (G.AdjMatrix[start-1][end-1] == INFINITY) {
		cout << G.AdjMatrix[start - 1][end - 1] << endl;
		cout << "当前两节点之间无边" << endl;
		return;
	}
	G.AdjMatrix[start-1][end-1] = G.AdjMatrix[end-1][start-1] = INFINITY;
	G.arcnum--;
	cout << "删除成功" << endl;
}

void DelVertex(MGraph &G) {
	int number;
	cout << "请输入您想删去的结点的编号" <<endl;
	cin >> number;
	if (number<1 || number>G.vexnum) {
		cout << "您的输入有误,请重新输入" << endl;
	}
	int count = 0;
	//删去顶点v和所有与之关联的边
	for (int i = 0; i < G.vexnum; i++) {
		if (!(G.AdjMatrix[i][number-1] == INFINITY)) {
			G.AdjMatrix[i][number - 1] = G.AdjMatrix[number - 1][i] = INFINITY;
			count++;
		}
	}
	G.vex[number - 1].name = "NULL";
	G.vex[number - 1].info = "NULL";
	PrintAllInfo(G);
}

void AddVertex(MGraph &G){
	string name;
	string info;
	cout << "请您输入您要增加的景点的名称" << endl;
	cin >> name;
	for (int i = 0; i < G.vexnum; i++){
		if (name == G.vex[i].name){
			cout << "您要增加的景点已经存在!" << endl;
			return;
		}
	}

	cout << "请您输入您要增加的景点的简介" << endl;
	cin >> info;
	int n = G.vexnum;
	G.vex[n].Num = G.vexnum;
	G.vex[n].name  ="name";
	G.vex[n].info = "info";
	G.vexnum++;
	cout << "已成功增加景点!" << endl;
	cout << endl;
}

void AddArc(MGraph &G) {
	int start;
	int end;//start和end都是从1开始
	cout << "请输入您想增加的边的起始结点" << endl;
	cin >> start;
	if (start < 1 || start>G.vexnum) {
		cout << "您输入的结点不存在" << endl;
		return;
	}
	cout << "请输入您想增加的边的结束结点" << endl;
	cin >> end;
	if (end < 1 || end > G.vexnum) {
		cout << "您输入的结点不存在" << endl;
		return;
	}
	if (start == end) {
		cout << "当前输入的两个节点相同" << endl;
		return;
	}
	if (!(G.AdjMatrix[start-1][end-1] == INFINITY)) {
		cout << "当前两节点之间已有边" << endl;
		return;
	}
	int weight;
	cout << "请输入您想增加的边的权重" << endl;
	cin >> weight;
	G.AdjMatrix[start-1][end-1] = G.AdjMatrix[end-1][start-1] = weight;
	cout << "增加成功" << endl;
	G.arcnum++;
}

void UpdateIifo(MGraph &G) {
	//更新景点信息
	int number;
	string info;
	string name;
	cout << "请输入您想更新的景点的编号" << endl;
	cin >> number;
	if (number<1 || number>G.vexnum) {
		cout << "您的输入有误,请重新输入" << endl;
		return;
	}
	cout << "请输入景点新的信息" << endl;
	cin >> info;
	cout << info << endl;
	G.vex[number - 1].info = info;
	cin >> name;
	cout << name << endl;
	G.vex[number - 1].name = name;
	cout << "修改成功" << endl;
	PrintAllInfo(G);
}

void PrintAdj(MGraph& G) {
	for (int i = 0; i < G.vexnum; i++) {
		for (int j = 0; j < G.vexnum; j++) {
			cout << G.AdjMatrix[i][j] << " ";
		}
		cout << endl;
	}
}

//prim算法求最小生成树
void Prim(MGraph &G){  
	cout << "请输入您想从几号景点" << endl;
	int choice;
	cin >> choice;
	struct{
		int adjvex;
		int lowcost;
	}closedge[MAXVEX];
	int i, e, k, m, min;
	closedge[choice].lowcost = 0;
	for (i = 0; i < G.vexnum; i++)
		if (i != choice-1)
		{
			closedge[i].adjvex = choice - 1;
			closedge[i].lowcost = G.AdjMatrix[choice - 1][i];
		}
	for (e = 0; e < G.vexnum - 1; e++){
		min = INFINITY;
		for (k = 0; k < G.vexnum; k++){
			if (closedge[k].lowcost != 0 && closedge[k].lowcost < min){
				m = k;
				min = closedge[k].lowcost;
			}
		}
		printf("从%s<------>%s:%dm\n", G.vex[closedge[m].adjvex].name, G.vex[m].name, closedge[m].lowcost);
		closedge[m].lowcost = 0;
		//当m加入后,更新closedge数组信息
		for (i = 0; i < G.vexnum; i++){
			if (i != m && G.AdjMatrix[m][i] < closedge[i].lowcost){
				closedge[i].lowcost = G.AdjMatrix[m][i];
				closedge[i].adjvex = m;
			}
		}
	}
}
int main() {
	cout << "欢迎来到江苏科技大学长山校区" << endl;
	MGraph G;
	InitGraph(G);//初始化
	Menu();//用户看到菜单
	bool flag = true;
	while (flag) {
		cout << "请输入您的选择:" << endl;
		int choice;
		cin >> choice;
		switch (choice) {
		case 1:
			MapDisplay();
			break;
		case 2:
			PrintAllInfo(G);
			break;
		case 3:
			Floyd(G);
			ShortestPathOfAnyTwo(G);
			break;
		case 4:
			AddVertex(G);
			break;
		case 5:
			DelVertex(G);
			break;
		case 6:
			AddArc(G);
			break;
		case 7:
			DelArc(G);
			break;
		case 8:
			UpdateIifo(G);
			break;
		case 9:
			PrintAdj(G);
			break;
		case 10:
			Prim(G);
			break;
		case 0:
			cout << "感谢您的使用,再见" << endl;
			flag = false;
			break;
		default:
			cout << "您的输入有误,请重新输入" << endl;
		};
	}
}

五.测试结果及其分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这个项目总体来说并不难,主要的一个函数就是求两个景点之间的最短路径,可以用**迪杰特斯拉算法(Dijkstra)和弗洛伊德算法(Floyd)**来解决,这里我选的是后者,以下是关于Floyd算法的简介:

基本思想:
**弗洛伊德算法定义了两个二维矩阵:**
矩阵D记录顶点间的最小路径
例如D[0][3]= 10,说明顶点03 的最短路径为10;
矩阵P记录顶点间最小路径中的中转点
例如P[0][3]= 1 说明,03的最短路径轨迹为:0 -> 1 -> 3。
它通过3重循环,k为中转点,v为起点,w为终点,循环比较D[v][w]D[v][k] + D[k][w] 最小值,如果D[v][k] + D[k][w] 为更小值,则把D[v][k] + D[k][w] 覆盖保存在D[v][w]中。
**算法的核心是中转和三重循环。**

在写这个项目的过程中,没有遇到什么太大的问题,遇到的问题主要是系统函数的调用以及下标刚开始的时候有些混乱。

六.用户使用说明

七.参考文献

[1] 张磊编著《C语言程序设计教程第2版》 中国铁道出版社
[2] 薛小龙编著《开发日记:深入体验C语言项目开发》清华大学出版社
[3] 刘字君张月琴叶瑶王庆生编著《C+理序设计案例分析》 清华大学出版社

附录

项目三:算术表达式求解

一.内容与相关要求;

问题描述:设计一个简单的算术表达式计算器
基本要求:实现标准整数类型的四则运算表达式的求值(包含括号,可以多层嵌入)

二.问题分析和任务定义;

算术表达式求解是一个经典的栈的应用;

三.数据结构的选择和概要设计;

选择栈这个数据结构。

3.1 数据结构的选择

3.2 概要设计

3.2.1 总体设计

使用模板函数建立顺序链表,计算表达式结果时,把中缀表达式转换为后缀表达式进行计算,因为计算机更容易处理后缀表达式。

3.2.2 功能函数的设计
SeqStack()构造函数,栈的初始化
Push(T x)元素x入栈
Pop()栈顶元素出栈
GetTop()获得栈顶元素,但是栈顶元素不出栈
Empty()判断栈是否为空
Top()返回栈顶值
Infi_to_Suffix(char* in, char* houzhui)中缀转后缀函数
Calculate(char* houzhui)计算后缀表达式
panduan( char ch)判断是否是运算符

四.详细设计和编码;

4.1 程序流程图

4.2 详细代码

4.2.1 模板定义
const int StackSize = 100;
template<class T>
class SeqStack {
public:
	SeqStack();//构造函数,栈的初始化
	~SeqStack() {};//析构函数
	void Push(T x);//元素x入栈
	T Pop();//栈顶元素出栈
	T GetTop();//获得栈顶元素,但是栈顶元素不出栈
	bool Empty();//判断栈是否为空
	int Top() {
		return top;
	}//返回栈顶值
private:
	T data[StackSize];
	int top;
};
4.2.2 SeqStack() 构造函数
template<class T>
SeqStack<T>::SeqStack() {
	top = -1;
}
4.2.3 Push(T x) 元素x入栈函数
template<class T>
void SeqStack<T>::Push(T x) {
	if (top == StackSize - 1) {
		throw"栈上溢";
	}
	data[++top] = x;
}
4.2.4 Pop() 栈顶元素出栈函数
template<class T>
T SeqStack<T>::Pop() {
	if (top == -1) {
		throw"栈下溢";
	}
	else {
		T x = data[top--];
		return x;
	}
}
4.2.5 GetTop()
template<class T>
T SeqStack<T>::GetTop() {
	if (top != -1) {
		return data[top];
	}
	else {
		throw"栈下溢";
	}
}
4.2.6 Empty() 判断栈是否为空函数
template<class T>
bool SeqStack<T>::Empty() {
	if (top == -1) {
		return 1;
	}
	else {
		return 0;
	}
}
4.2.7 Infi_to_Suffix(char* in, char* houzhui) 中缀转后缀函数
void Infi_to_Suffix(char* in, char* houzhui) {
	SeqStack<char> Operator_T;
	int flag = 0;
	//left和right用来记录算式里面左右括号的个数
	int left = 0;
	int right = 0;
	int number = 0;
	for (int i = 0, j = 0; in[i] != '#'; i++) {
		switch (in[i]) {
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		{
			int num = i + 1;
			if (in[i] >= '0' && in[i] <= '9' && in[num] >= '0' && in[num] <= '9') {
				int number = 10 * (in[i] - 48) + (in[num] - 48);
				char ch = number + '0';
				houzhui[j] = ch;
				i++;
				j++;
				flag = 1;
			}
			else {
				houzhui[j] = in[i];//如果是数字,加到后缀数组中
				j++;
				flag = 1;
			}
		}
			//houzhui[j] = in[i];//如果是数字,加到后缀数组中
			//j++;
			//flag = 1;
			break;
		case '(':
			//括号前面是数字,报错
			if (flag) {
				cout << "数字后直接跟括号" << endl;
				exit(0);
			}
			//加到操作符栈中
			Operator_T.Push(in[i]);
			//左括号数加一 
			left++;
			break;
		case ')':
			//右括号数加一 
			right++;
			//如果扫描到的运算符是右括号的话,那就把栈中左括号之前的操作符出栈,加到后缀表达式中
			while (Operator_T.GetTop() != '(') {
				houzhui[j] = Operator_T.Pop();
				j++;
			}
			//while做完之后,Operator_T的栈顶是'(',直接抛出,和')'抵消
			Operator_T.Pop();
			break;
		case '+':
		case '-':
			//如果运算符前面还是运算符,报错
			if (!flag && i != 0) {
				cout << "两个连续的运算符" << endl;
				exit(0);
			}
			if (i == 0) {
				houzhui[j] = '0';
				j++;
			}
			flag = 0;
			//由于优先级的原因,+ - 这两个运算符的优先级只小于'('
			//原则:如果当前扫描到的操作符比现在栈顶操作符的优先级大的话,那么就入栈;否则,栈顶操作符出栈,继续比较,直到满足条件为止
			while (!Operator_T.Empty() && Operator_T.GetTop() != '(') {
				houzhui[j] = Operator_T.Pop();
				j++;
			}
			//做完之后,栈顶的元素优先级肯定小于+ -,入栈
			Operator_T.Push(in[i]);
			break;
		case '*':
			//如果运算符前面还是运算符,报错
			if (!flag) {
				cout << "两个连续的运算符" << endl;
				exit(0);
			}
			flag = 0;
			//由于优先级的原因
			while (!Operator_T.Empty() && Operator_T.GetTop() == '/') {
				houzhui[j] = Operator_T.Pop();
				j++;
			}
			//做完之后,栈顶的优先级肯定小于'*','*'入栈
			Operator_T.Push(in[i]);
			break;
		case '/':
			//如果运算符前面还是运算符,报错
			if (!flag) {
				cout << "两个连续的运算符" << endl;
				exit(0);
			}
			flag = 0;
			//由于优先级的原因
			while (!Operator_T.Empty() &&( Operator_T.GetTop() == '/'||Operator_T.GetTop()=='*')) {
				houzhui[j] = Operator_T.Pop();
				j++;
			}
			//做完之后,栈顶的优先级肯定小于'/','/'入栈
			Operator_T.Push(in[i]);
			break;
			//实际上,扫描到的操作符是乘号的这种情况包含在了扫描到的操作符是除号这种情况里面,这里代码可以缩减
		default:
			cout << "非法字符" << endl;
			exit(0);
		}
		number = j;
	}
	if (left != right){
		cout << "左右括号不匹配" << endl;
		exit(0);
	}
	while (!Operator_T.Empty()){
		houzhui[number] = Operator_T.Pop();
		number++;
	}
	houzhui[number] = '\0';
}
4.2.8 panduan( char ch)
bool panduan(char ch) {
	if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
		return true;
	}
	return false;
}
4.2.9 Calculate(char* houzhui) 计算后缀表达式的值
void Calculate(char* houzhui) {
	SeqStack<double>number;
	double answer = 0;
	for (int i = 0; houzhui[i] != '\0'; i++) {
		if (panduan(houzhui[i])==false) {
			number.Push(houzhui[i] - '0');
		}
		else {
			int opd2 = number.Pop();
			int opd1 = number.Pop();
			switch (houzhui[i]) {
			case '+':
				number.Push(opd1 + opd2);
				break;
			case '-':
				number.Push(opd1 - opd2);
				break;
			case '*':
				number.Push(opd1 * opd2);
				break;
			case '/':
				if (fabs(opd2) < 1e-6) {
					cout << "Diveded by 0!" << endl;
					exit(0);
				}
				answer = (double) opd1/opd2;
				cout << answer << endl;
				number.Push(answer);
				break;
			default:
				cout << "非法符号" << endl;
				break;
			}
		}
	}
	cout << "结果为:" << endl;
	cout << number.Pop() << endl;
}

4.3 完整代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include<iostream>
using namespace std;
const int StackSize = 100;
template<class T>
class SeqStack {
public:
	SeqStack();//构造函数,栈的初始化
	~SeqStack() {};//析构函数
	void Push(T x);//元素x入栈
	T Pop();//栈顶元素出栈
	T GetTop();//获得栈顶元素,但是栈顶元素不出栈
	bool Empty();//判断栈是否为空
	int Top() {
		return top;
	}//返回栈顶值
private:
	T data[StackSize];
	int top;
};
template<class T>
SeqStack<T>::SeqStack() {
	top = -1;
}
template<class T>
void SeqStack<T>::Push(T x) {
	if (top == StackSize - 1) {
		throw"栈上溢";
	}
	data[++top] = x;
}
template<class T>
T SeqStack<T>::Pop() {
	if (top == -1) {
		throw"栈下溢";
	}
	else {
		T x = data[top--];
		return x;
	}
}
template<class T>
T SeqStack<T>::GetTop() {
	if (top != -1) {
		return data[top];
	}
	else {
		throw"栈下溢";
	}
}
template<class T>
bool SeqStack<T>::Empty() {
	if (top == -1) {
		return 1;
	}
	else {
		return 0;
	}
}
int shuzi[10];
char Operator[10];

void Infi_to_Suffix(char* in, char* houzhui) {
	SeqStack<char> Operator_T;
	int flag = 0;
	//left和right用来记录算式里面左右括号的个数
	int left = 0;
	int right = 0;
	int number = 0;
	for (int i = 0, j = 0; in[i] != '#'; i++) {
		switch (in[i]) {
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		{
			int num = i + 1;
			if (in[i] >= '0' && in[i] <= '9' && in[num] >= '0' && in[num] <= '9') {
				int number = 10 * (in[i] - 48) + (in[num] - 48);
				char ch = number + '0';
				houzhui[j] = ch;
				i++;
				j++;
				flag = 1;
			}
			else {
				houzhui[j] = in[i];//如果是数字,加到后缀数组中
				j++;
				flag = 1;
			}
		}
			//houzhui[j] = in[i];//如果是数字,加到后缀数组中
			//j++;
			//flag = 1;
			break;
		case '(':
			//括号前面是数字,报错
			if (flag) {
				cout << "数字后直接跟括号" << endl;
				exit(0);
			}
			//加到操作符栈中
			Operator_T.Push(in[i]);
			//左括号数加一 
			left++;
			break;
		case ')':
			//右括号数加一 
			right++;
			//如果扫描到的运算符是右括号的话,那就把栈中左括号之前的操作符出栈,加到后缀表达式中
			while (Operator_T.GetTop() != '(') {
				houzhui[j] = Operator_T.Pop();
				j++;
			}
			//while做完之后,Operator_T的栈顶是'(',直接抛出,和')'抵消
			Operator_T.Pop();
			break;
		case '+':
		case '-':
			//如果运算符前面还是运算符,报错
			if (!flag && i != 0) {
				cout << "两个连续的运算符" << endl;
				exit(0);
			}
			if (i == 0) {
				houzhui[j] = '0';
				j++;
			}
			flag = 0;
			//由于优先级的原因,+ - 这两个运算符的优先级只小于'('
			//原则:如果当前扫描到的操作符比现在栈顶操作符的优先级大的话,那么就入栈;否则,栈顶操作符出栈,继续比较,直到满足条件为止
			while (!Operator_T.Empty() && Operator_T.GetTop() != '(') {
				houzhui[j] = Operator_T.Pop();
				j++;
			}
			//做完之后,栈顶的元素优先级肯定小于+ -,入栈
			Operator_T.Push(in[i]);
			break;
		case '*':
			//如果运算符前面还是运算符,报错
			if (!flag) {
				cout << "两个连续的运算符" << endl;
				exit(0);
			}
			flag = 0;
			//由于优先级的原因
			while (!Operator_T.Empty() && Operator_T.GetTop() == '/') {
				houzhui[j] = Operator_T.Pop();
				j++;
			}
			//做完之后,栈顶的优先级肯定小于'*','*'入栈
			Operator_T.Push(in[i]);
			break;
		case '/':
			//如果运算符前面还是运算符,报错
			if (!flag) {
				cout << "两个连续的运算符" << endl;
				exit(0);
			}
			flag = 0;
			//由于优先级的原因
			while (!Operator_T.Empty() &&( Operator_T.GetTop() == '/'||Operator_T.GetTop()=='*')) {
				houzhui[j] = Operator_T.Pop();
				j++;
			}
			//做完之后,栈顶的优先级肯定小于'/','/'入栈
			Operator_T.Push(in[i]);
			break;
			//实际上,扫描到的操作符是乘号的这种情况包含在了扫描到的操作符是除号这种情况里面,这里代码可以缩减
		default:
			cout << "非法字符" << endl;
			exit(0);
		}
		number = j;
	}
	if (left != right){
		cout << "左右括号不匹配" << endl;
		exit(0);
	}
	while (!Operator_T.Empty()){
		houzhui[number] = Operator_T.Pop();
		number++;
	}
	houzhui[number] = '\0';
}
bool panduan(char ch) {
	if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
		return true;
	}
	return false;
}
void Calculate(char* houzhui) {
	SeqStack<double>number;
	double answer = 0;
	for (int i = 0; houzhui[i] != '\0'; i++) {
		if (panduan(houzhui[i])==false) {
			number.Push(houzhui[i] - '0');
		}
		else {
			int opd2 = number.Pop();
			int opd1 = number.Pop();
			switch (houzhui[i]) {
			case '+':
				number.Push(opd1 + opd2);
				break;
			case '-':
				number.Push(opd1 - opd2);
				break;
			case '*':
				number.Push(opd1 * opd2);
				break;
			case '/':
				if (fabs(opd2) < 1e-6) {
					cout << "Diveded by 0!" << endl;
					exit(0);
				}
				answer = (double) opd1/opd2;
				cout << answer << endl;
				number.Push(answer);
				break;
			default:
				cout << "非法符号" << endl;
				break;
			}
		}
	}
	cout << "结果为:" << endl;
	cout << number.Pop() << endl;
}
void main() {
	cout << "请输入表达式,以#结尾" << endl;
	string a;
	cin >> a;
	char zhongzhui[20];
	char houzhui[20];
	for (int i = 0; i < a.length(); i++) {
		zhongzhui[i] = a[i];
	}
	Infi_to_Suffix(zhongzhui,houzhui);
	for (int i = 0; houzhui[i] != '\0'; i++) {
		cout << houzhui[i] << endl;
	}
	//后缀里面没有#
	Calculate(houzhui);
}

五.测试结果及其分析;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此函数基本功能均已实现,但是对于负数的情况还没有实现,读者可以根据自己的需要在此基础上进行更改。对于常见的三种报错(连续运算符,非法字符,分母为0),代码也都能检测出来。

六.用户使用说明;

七.参考文献;

[1] 李文书.数据结构与算法应用实践教程.北京大学出版社. 2012. 02
[2]戴文华赵君喆.数据结构项目实训.人民邮电出版社. 2012. 09
[3] 李业丽程晓锦齐亚莉.数据结构实验教程(基于c语言).清华大学出版社. 2014. 04

附录;

  • 17
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值