数据结构与算法——教学编制计划——Java

教学编制计划—Java

1. 问题描述

大学的每个专业都要制定教学计划。假设任何专业都有固定的学习年限,每学年含两学期,每学期的时间长度和学分上限值均相等。每个专业开设的课程都是确定的,而且课程在开设时间的安排必须满足先修关系。每门课程有哪些先修课程是确定的,可以有任意多门,也可以没有。每门课恰好占一个学期。试在这样的前提下设计一个教学计划编制程序。

2.基本要求

  1. 输入参数包括:学期总数,一学期的学分上限,每门课的课程号(固定占3位的字母数字串)、学分和直接先修课的课程号。
  2. 允许用户指定下列两种编排策略之一:一是使学生在各学期中的学习负担尽量均匀;二是使课程尽可能地集中在前几个学期中。
  3. 若根据给定的条件问题无解,则报告适当的信息,否则将教学计划输出到用户指定的文件中。计划的表格格式自行设计。

3.题目分析

  • 首先课程与课程之间的关系是多对多的关系,在数据结构中这是属于图形结构。图的结点包括课程号、课程名、学分、先修关系这些属性。
  • 其次本题的难点除了最后的平均排课和集中排课方法以外,就是将课程之间的先修关系表现出来。在图结构中,拓扑排序恰好可以表示这一关系。拓扑排序可以使用栈(排序后唯一)或者队列(多种排序结果)进行排序。以为这里不需要唯一性,所以我使用了队列。
  • 最后排课的两个方法,比较容易的是集中排序,平均排序就要多下点功夫了。因为我懒~所以这里将数据保存在MySQL数据库中,这样就不用再测试时频繁的输入了,然后用Servlet 将结果发送到网页进行显示。因为程序比较简单,所以没用框架什么的。

4.类的具体实现以及结果截图

在这里插入图片描述
图 4-1 类的创建结果截图
效果截图图 4-2 效果截图

5.主要代码片段

//生成拓扑排序后的图,并返回
public class CreateGraph {
	static Scanner scanner=new Scanner(System.in);
	static int inDegree[];
	//用邻接表存储图
	public void  initialGraph(Graph graph,MySQL mysql) {
		inDegree = new int[graph.vertexNum+1];
		List<Edge> temp=new ArrayList<Edge>();
		//数据库读取
		try {
			temp=mysql.getValue();
		} catch (SQLException e) {
			System.out.println("引用有误");
			e.printStackTrace();
		}
		//判断入度的个数
		for(int i = 0; i < temp.size(); i++){
			int u = temp.get(i).start;
			int v = temp.get(i).end;
			graph.vlist[u].add(v);
			inDegree[v]++;
		}
	}
		//拓扑排序
	public ArrayList<Vertex> topologicalSort(Graph graph,MySQL mysql) {
		ArrayList<Vertex> list=new ArrayList<>();
		Queue<Integer> queue = new LinkedList<>();
		//检查入度为零的顶点
		for(int i = 1; i <=graph.vertexNum; i++){
			if(inDegree[i] == 0){
				queue.add(i);
			}
		}
		while(!queue.isEmpty()){
			int u = queue.poll();
			try {
				Inform inform=mysql.getinformation(u);
				String vlaue=inform.value;
				String name=inform.name;
				int score=inform.score;
				list.add(new Vertex(vlaue,name,score));
			} catch (SQLException e) {
				e.printStackTrace();
			}
			for(int i = 0; i < graph.vlist[u].size(); i++){
				int v = graph.vlist[u].get(i);
				inDegree[v]--;
				if(inDegree[v] == 0)
					queue.add(v); 
			}
		}
		return list;
	}
}
//	集中排序
	public Map<Integer,Object > makeFirst() {
	ArrayList<Vertex> list = allList();
		ArrayList<Vertex> list1 =new ArrayList<Vertex>();
		//这里是存放到HashMap中,最后返回到到网页页面中
		Map<Integer, Object> map = new HashMap<>(8);
		int stuNum = 8;//学期数
		int max = 6;//最大学分
		int j = 0;//临时下标
		int tol=0;
		for(int i= 1 ; i <= stuNum;i++) {
				while(true){
					if(j<=list.size()-1) {
					tol += list.get(j).score;
						if(tol <= max ) {
							list1.add(list.get(j));
							j++;
						}else {
							map.put(i,list1);
							tol=0;
							list1=new  ArrayList<Vertex>();
							break;
						 }
				}else {
					break;
				}
				}if(j>list.size()-1) {
					list1.add(new Vertex("无","无",0));
					map.put(i,list1);
					list1=new  ArrayList<Vertex>();
					j++;
				}
		}
			return map;
		}
//平均分布
	public Map<Integer,Object> makeSecond() {
		ArrayList<Vertex> list = allList();
		ArrayList<Vertex> list1 =new ArrayList<Vertex>();
		Map<Integer, Object> map=new HashMap<>(8);
		int stuNum = 8;//学期数
		int max = 6;//最大学分
		int j = 0;//临时下标
		for(int i =1 ; i <= stuNum ; i++) {
			if(j<=list.size()-2){
				while(true){	
					int a = list.get(j).score;
					if(a < max / 2 ) {
						list1.add(list.get(j));
						list1.add(list.get(j+1));
						map.put(i,list1);
						list1=new  ArrayList<Vertex>();
						j+=2;
						break;
					}else {
						list1.add(list.get(j));
						map.put(i,list1);
						list1=new  ArrayList<Vertex>();
						j++;
						break;
					}
				}
			}else if(j == list.size()-1){
				list1.add(list.get(j));
				map.put(i,list1);
				j++;
			}else {
				list1.add(new Vertex("无","无",0));
				map.put(i,list1);
				list1=new  ArrayList<Vertex>();
			}
		  }
			return map;
	 }
   }

6.总结

一开始没有连接数据库,就是用System.out.println不断的进行输出判定,因为效率问题采用了数据库存储的方法,使用时只要读取数据库的数据即可。提高平时运算的效率。虽然可以最后显示出来了,但初次写的代码肯定有优化的空间。只有不断的实验和诊断才能写成一个可以适用的好程序。总之,以后的路还很长,学习的东西还有很多。每次的课程设计都是对自己能力的提升,感谢老师同学的帮助与支持。

发布了12 篇原创文章 · 获赞 5 · 访问量 647

猜你喜欢

转载自blog.csdn.net/qq_44091773/article/details/103985205