【算法】座位排序算法

一、前言

      在这里,小编想向大家说明一下需求,在很多的系统中,比如电影院的选座系统、飞机取登机牌选座系统等,都有一个选座位的功能。可见,选座位在我们的生活中还是很常用的。

      小编就在最近的考试系统中,带领团队研究了一个考场分配座位的系统——电子准考证。下面小编就从两种分配方式来介绍一下。

二、需求说明

      这里得说一下全局观,首先呢,每个考场会在不同的日期、不同的时间段安排学生参加考试。考生可以通过微信平台提前查询自己的考试信息,包括考试科目、考试时间、考试地点、考试座位号。通过不同的排座位的算法,达到:

  • 可以使得一个考场的人随机分配座位

  • 使得一个考场的学生按照班级分配座位

  • 跳过不能使用的座位

三、全场随机抽取座位

      随机抽取座位业务流程图:

这里写图片描述

      这里的核心技术点就是建立一个bool数组,数组的大小和本场考试的学生个数相同,然后获取已经分配了的作为,把分配了的座位打上标记。然后随机产生一个数,判断这个座位的是否有人。如果有人就不分配,如果没有人就分配。就是这么简单。

      这个操作也同样在考试的题库抽题中适用。

        #region 随机不重复座位号-王雷-2017年6月18日10:32:44
        /// <summary>
        /// 随机不重复座位号-王雷-2017年6月18日10:32:44
        /// </summary>
        /// <returns></returns>
        public string RandSeatNum(StudentExamInfoEntity seie)
        {
            //获取考场号,日期,时间
            string examPlace = seie.ExamPlace.Split('-')[0];
            string ExamDate = seie.ExamDate;
            string startTime = seie.StartTime;
            //实例化D层
            RandSeatNumHelper randSeatNumHelper = new RandSeatNumHelper();
            //根据考场号,日期,时间从基础库中查出这一场有多少人,获得max的值
            int max = randSeatNumHelper.SelectPopulationInExam(examPlace, ExamDate, startTime);
            //根据考场号,日期,时间从本地库中查已经分配的座位号
            DataTable dt = randSeatNumHelper.SelectSeat(examPlace, ExamDate, startTime);
            //生成随机数
            //实例化bool数组
            bool[] flag = new bool[max + 1];
            //把已经分配过的座位号标记成true
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                int seat = Convert.ToInt32(dt.Rows[i][0]);
                flag[seat] = true;
            }
            //生成随机数
            for (int j = 1; j <= max; j++)
            {
                Random rm = new Random();
                int newSeat = rm.Next(1, max + 1);
                if (!flag[newSeat])
                {
                    return newSeat.ToString();
                }
            }
            return null;
        }
        #endregion

四、全场按班级学号分组排序

      时序流程图:

这里写图片描述

      在这里,用到的代码核心就是当a

 #region 获取座位号-王雷-2017年6月23日15:03:09
        /// <summary>
        /// 获取座位号-王雷-2017年6月23日15:03:09
        /// </summary>
        /// <param name="seie"></param>
        /// <returns></returns>
        public int QueryStudentSeatNum(StudentExamInfoEntity seie)
        {
            //获取考场号,日期,时间
            string examPlace = seie.ExamPlace.Split('-')[0];
            string ExamDate = seie.ExamDate;
            string startTime = seie.StartTime;
            string studentNo = seie.StudentNo;
            //实例化D层
            RandSeatNumHelper randSeatNumHelper = new RandSeatNumHelper();
            int seatNum = randSeatNumHelper.QueryStudentSeatNum(examPlace, ExamDate, startTime, studentNo);

            string countAll = QueryAllSeatNum(examPlace);
            if (seatNum < Convert.ToInt32(countAll))
            {
                //判断座位是否可以使用
                while (!QuerySeatUseful(examPlace, seatNum) || !QuerySeatBeenTaken(examPlace, ExamDate, startTime, seatNum))
                {
                    //不可使用
                    seatNum = seatNum + 1;
                }
                //当座位可以使用的时候
                return seatNum;
            }
            else if (seatNum == Convert.ToInt32(countAll))
            {
                //判断座位是否可以使用
                if (QuerySeatUseful(examPlace, seatNum))
                {
                    //座位可以使用,判断座位是否已经被占用
                    if (QuerySeatBeenTaken(examPlace, ExamDate, startTime, seatNum))
                    {
                        //座位没有被占用,可以使用
                        return seatNum;
                    }
                    return -1;
                }
                return -1;
            }
            else
            {
                return -1;
            }
        }
        #endregion

      按照班级抽取预座位:

 #region 按照班级分配座位-王雷-2017年6月23日15:58:30
        /// <summary>
        /// 按照班级分配座位-王雷-2017年6月23日15:58:30
        /// </summary>
        /// <param name="examPlace">考试地点</param>
        /// <param name="ExamDate">考试日期</param>
        /// <param name="startTime">考试开始时间</param>
        /// <param name="studentNo">学生学号</param>
        /// <returns>int</returns>
        public int QueryStudentSeatNum(string examPlace, string ExamDate, string startTime, string studentNo)
        {
            SQLHelper sqlHelper = new SQLHelper("connStr");
            string strSql = " select * FROM (select top 100 percent row_number() over (order by StudentNo) as rowNum ,StudentNo FROM V_StudentExamInfo where ExamDate ='" + ExamDate + "' and StartTime ='" + startTime + "'  AND ExamPlace like '" + examPlace + "%' ORDER BY StudentNo) as b where b.StudentNo ='" + studentNo + "'";
            DataTable dt = sqlHelper.ExecuteQuery(strSql, CommandType.Text);
            return Convert.ToInt32(dt.Rows[0]["rowNum"]);
        } 
        #endregion

      判断座位是否可以使用:

#region 判断座位是否可以使用-王雷-2017年7月3日10:55:38
        /// <summary>
        /// 判断座位是否可以使用-王雷-2017年7月3日10:55:38
        /// </summary>
        /// <param name="examPlace">考场</param>
        /// <param name="seatNum">座位</param>
        /// <returns>bool</returns>
        public bool QuerySeatUseful(string examPlace, int seatNum)
        {

            string sql = "SELECT * FROM t_computer WHERE RoomNo = @examPlace and SeatNo=@seatNum and IsUse ='1'";
            MySqlParameter[] parameters = new MySqlParameter[]
            {
                new MySqlParameter("@examPlace",examPlace),
                new MySqlParameter("@seatNum",seatNum )

            };

            DataTable dt = new DataTable();
            try
            {
                //调用sqlhelper的方法得到结果
                dt = MySqlHelper.ExecuteDataTable(sql, parameters);
                if (dt != null && dt.Rows.Count > 0)
                {
                    //可以使用
                    return true;
                }
                else
                {
                    //不可以使用
                    return false;
                }
            }
            catch (Exception ex)
            {
                //错误展出
                WriteLog.WriteError(ex.ToString());
                throw;
            }
        } 
        #endregion

      查询座位是否已经被占用:

#region 查询座位是否已经被占用-王雷-2017年7月3日16:07:51
        /// <summary>
        /// 查询座位是否已经被占用-王雷-2017年7月3日16:07:51
        /// </summary>
        /// <param name="examPlace"></param>
        /// <param name="ExamDate"></param>
        /// <param name="startTime"></param>
        /// <param name="seatNo"></param>
        /// <returns></returns>
        public bool QuerySeatBeenTaken(string examPlace, string ExamDate, string startTime, int seatNo)
        {
            //判断座位是否已经被占用
            string sql = "select * from t_exambasicinfo where ExamPlace like @examPlace and Date=@ExamDate and StartTime=@startTime and SeatNo=@seatNo";

            MySqlParameter[] parameters = new MySqlParameter[]
            {
                new MySqlParameter("@examPlace",examPlace+"%"),
                new MySqlParameter("@ExamDate",ExamDate ),
                new MySqlParameter("@startTime",startTime ),
                new MySqlParameter("@seatNo",seatNo )

            };

            DataTable dt = new DataTable();
            try
            {
                //调用sqlhelper的方法得到结果
                dt = MySqlHelper.ExecuteDataTable(sql, parameters);
                if (dt != null && dt.Rows.Count > 0)
                {
                    //座位已经被占用,不能使用
                    return false;
                }
                else
                {
                    //可以使用
                    return true;
                }
            }
            catch (Exception ex)
            {
                //错误展出
                WriteLog.WriteError(ex.ToString());
                throw;
            }
        } 
        #endregion

五、小结

      这个是一个神奇的故事。

      算法就是一个神奇的故事,当我们在学习,在想如何实现一个功能的时候,这个路子就是我们自己编辑的算法。算法也是在不断的摩擦中不断改进的。加油!

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你个佬六

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值