考场自动安排工具开发手记

昨天教务的一个同事,提出有没有办法可以对169门考试(合计1744个学生)进行考试安排。因为是期末考试补考。因此其中很多考试存在学生冲突现象。

例如:

(英语翻译2-2<--->英语听力4-4) ID:200616031109
(英语专业四级培训-3<--->英语听力4-4) ID:200616031133
(英语翻译2-2<--->英语听力4-4) ID:200616031109
(英语专业四级培训-3<--->英语听力4-4) ID:200616031133
(英语翻译2-2<--->英语听力4-4) ID:200616031109
(英语专业四级培训-3<--->英语听力4-4) ID:200616031133
(英语听说2-2<--->大学英语听说4-2) ID:200616013260
(英语听说2-2<--->合同法案例实践-2) ID:200616041257

存在冲突的考试科目就不能安排在同一批次(也就是同一时间段内)

软件界面如图:

考场自动安排软件

软件工作流程:

(1)导入CSV数据文件。

文件格式为:

[学号]-[姓名]-[考试科目]

CSV文件导入代码:

/// <summary>
/// 将csv格式文件导成dataset
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="fileName">文件名</param>
/// <returns></returns>
public DataSet getCsv(string filePath, string fileName)
{
string strConn = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=";
strConn += filePath;
strConn += ";Extensions=asc,csv,tab,txt;";
OdbcConnection con = new OdbcConnection(strConn);
DataSet data = new DataSet();
string sql = "select * from " + fileName;
OdbcDataAdapter adp = new OdbcDataAdapter(sql, con);
con.Open();
adp.Fill(data, "csv");

return data;
}

(2)把导入的数据进行处理。

处理过程采用面向对象的思想,建立了一个考试类。

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ExamManager
{
public class Exam
{
public class student
{
public string studentID;
public string studentName;
}
public string ExamName;//考试科目
public string ExamTime;//考试时间
public int Students;//学生数

public ArrayList StudentList = new ArrayList(); //学生列表

public void addStudent(string studentID,string studentName)
{
student s = new student();
s.studentID = studentID;
s.studentName = studentName;

StudentList.Add(s);
}

public bool CheckStudentIdList(int N_PC,Exam ex,ref StringBuilder sb_ct)
{
ArrayList studIdList = ex.StudentList;

for (int i = 0; i < studIdList.Count; i++)
{
for (int j = 0; j < StudentList.Count; j++)
{
//考生 冲突
if (((student)studIdList[i]).studentID == ((student)StudentList[j]).studentID)
{
//Console.WriteLine("冲突:(" + ex.ExamName + "<--->" + this.ExamName + ") ID:" + ((student)studIdList[i]).studentID);
sb_ct.Append("批次:"+N_PC.ToString()+ " 冲突:(" + ex.ExamName + "<--->" + this.ExamName + ") ID:" + ((student)studIdList[i]).studentID);
sb_ct.Append("/r/n");
return false;
}
}
}


return true;
}

}
}

该类主要负责将CSV文件进行处理,把同一考试科目的学生归集到一起。其次是负责将2个考试对象进行检测,看看是否存在冲突。算法采用双重循环,效率较低。呵呵

(3)考试安排

public void KSAP()
{
//安排考试
ks_pc.Clear();//
Hashtable tmp = (Hashtable)htExams.Clone();
int i = 0;
int N_PC = 0;//批次

StringBuilder sb = new StringBuilder();
StringBuilder sb_ct = new StringBuilder();//冲突

loop:
foreach (DictionaryEntry ht in tmp)
{
if (i > int.Parse(txtKM_MAX.Text))
{
i = 0;
N_PC++;
}

//从 考试表中 取出1个
Exam e = (Exam)ht.Value;
object obj = ks_pc[N_PC];
if (obj == null)
{
//单前批次还没添加过,直接添加 当前考试
ArrayList al = new ArrayList();
ks_pc[N_PC] = al;
al.Add(e);
tmp.Remove(ht.Key);//移除单前考试,不在加入

i++;
sb.Append("/r/n----------------------------------/r/n");
//Console.WriteLine("New N_PC=" + N_PC.ToString() + " Exam:" + e.ExamName);
sb.Append("批次=" + N_PC.ToString() + " Exam:" + e.ExamName+" 人数:"+e.StudentList.Count);
sb.Append("/r/n");
goto loop;
}

//sb_ct.Append("/r/n----------------" + N_PC.ToString() + "--------------/r/n");
bool flag = true;
ArrayList ks = (ArrayList)obj; //获取考试列表
for (int j = 0; j < ks.Count; j++)
{
//开始检测
Exam le = (Exam)ks[j];

if (le.CheckStudentIdList(N_PC,e, ref sb_ct) == false)
{
//发现 冲突,不能将该考试添加进去
flag = false;//跳过该考试
}

}

if (flag == true)
{
//不存在冲突,可以添加进去
ks.Add(e);
tmp.Remove(ht.Key);
i++;
//Console.WriteLine("N_PC=" + N_PC.ToString() + " Exam:" + e.ExamName);
sb.Append("批次=" + N_PC.ToString() + " Exam:" + e.ExamName + " 人数:" + e.StudentList.Count);
sb.Append("/r/n");
goto loop;
}

}

if (tmp.Count > 0)
{
N_PC++;
goto loop;
}

//汇总信息
sb.Append("----------------------------------/r/n");
for (int N = 0; N <= N_PC; N++)
{
ArrayList ks=(ArrayList)ks_pc[N];
int num = 0;
for (int j = 0; j < ks.Count; j++)
{
//开始检测
Exam le = (Exam)ks[j];
num += le.StudentList.Count;
}

sb.Append("批次:" + N.ToString() + " 总人数=" + num.ToString() + "/r/n");
}
sb.Append("----------------------------------");
txtMSG.Text = sb.ToString();
txtCT.Text = sb_ct.ToString();

}

考试安排也是采用了循环+goto 实现,根据预先设置好的同一批次科目数,将不存在冲突的考试科目安排在一起。

整个程序的源代码,在共享里,欢迎大家交流。多多提出意见。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值