0
点赞
收藏
分享

微信扫一扫

基于课表的教室状态管理逻辑

北邮郭大宝 2022-03-26 阅读 44
算法java

1. 基本的数据库表

  • 教室基本信息表 classroom_baseinfo

    labelNamedescription
    classroomName教室名称
    classroomType多功能教室、普通教室、公共机房、阶梯教室、专业机房等
    classroomLevel院级、校级
    classroomHold教室的容量
  • 教室状态表 classroom_status

    labelNamedescription
    classroomName教室名称
    zc周次,24位数 ,011111111111111111000000; 或者 011111111111111_1100_0_0(下划线表示空闲)
    xqj1~7周1到周7
    djdj1~5 1到5大节
    classroomType多功能教室、普通教室、公共机房、阶梯教室、专业机房
    classroomLevel“院级"或者"校级”
    classroomStatus“被占用"或者"空闲中”
    classroomHold教室的容量
    classroomInfo暂时没用的字段

该表最初由两部分构成:

1.所有的教室信息(239条),其中zc设置为’0’,xqj和djdj设置为0,classroomName设置为其教室的名称。

2.课表改造出来的教室状态记录(7k多条)。

2. 查询逻辑

2.1 根据7个参数查询出某个时候某个的所有教室状态【链表合并+去重】

  • 参数

星期几xqj ,这个参数主要用于来确定筛选时间

第几大节djdj, 这个参数主要用于确定筛选时间

周次zc,这个参数主要用于确定筛选时间

教室类型classroomType,这个参数主要是用来筛选教室类型的(多功能教室等)

教室级别classroomLevel,这个参数主要是用来筛选院级教室或者校级教室的

教室区域classroomArea,这个参数主要是用来筛选教室位置的。

参与人数attenderNum, 这个参数主要用用来筛选教室的容量的。

  • 算法步骤:

Step1: 初始化教室状态链表list1和list2,讲它们置为空链表

Step2: 查询出符合所有要求(7个参数, 调用findAllBySevenCondition接口)的教室状态,并将结果链表赋值给list1。这样做的目的是查询出所有已经存在的教室状态,如被上课占用 或者 被申请占用的教室。比如博学楼的所有满足时间需求、容量需求的教室。

Step3: 查询出符合地点、容量、类型、级别的教室状态(4个参数,调用findAllByFourCondition接口),并将结果链表赋值给list2。这样做的目的是查询出所有满足地理空间条件的教室状态,以便为链表去重做准备(list2包含list1)。比如博学楼的所有满足容量需求的教室。list2中的状态元素的zc属性全为’0’

Step4: 把list2的元素全部放到list1中去,并准备一个hash表<ClassroomName, 1或者0>以备去重

Step5: 开启循环操作,判断是否已经遍历到链表的末尾了,如果是,则跳到Step9;否则进入下一步

Step6: 获取当前教室状态元素,判断教室状态元素的zc(周次)属性是否为’0’。如果该状态的zc属性不为’0’,说明这个教室的状态记录是存在于数据库表中的,那么使用hash表给该教室的名称标记上已存在(置为’1’),跳到Step8。如果为’0’,说明这个教室状态记录是教室本身的状态信息,进入Step7

Step7: 尝试从hash表中获取该教室状态元素的标记,如果获取的标记为‘1’,那么说明之前标记过,也即之前存在这个状态,所以这里就删除该为zc为’0’的元素。如果获取的标记为’0’,那么将这个教室状态的zc、xqj、djdj设置为查询参数的值,然后把classroomStatus字段设置为“空闲中”。

Step8:获取下一个链表元素

Step9: 返回去重后的list1并结束

在这里插入图片描述

时间复杂度O(m + n),m指所有满足空间条件的所有教室的数量,n指所有满足时间、空间条件已在数据库中存在记录的教室数量。

分析:查询出来的结果,会显示一部分被占用(之前存在的状态)、一部分空闲(剩下的教室状态)

代码:

public List<ClassroomStatus> getQueryList(String classroomType,String classroomArea,int classroomHold,String zc,int xqj,int djdj,String classroomLevel){
    List<ClassroomStatus> list1=null;
    List<ClassroomStatus> list2=null;
    List<ClassroomStatus> ans=null;
    /*查询符合所有要求的教室*/
    list1=statusDao.findAllBySevenCondition(classroomType,classroomArea,classroomHold,zc,xqj,djdj,classroomLevel);
    /*把所有符合时间、地点、容量、类型的教室都查出来*/
    list2=statusDao.findAllByFourCondition(classroomType,classroomArea,classroomHold,classroomLevel);
    /*把符合地点、容量、类型要求的教室都找了出来*/
    list1.addAll(list2);
    Map<String,Integer> map=new HashMap<String,Integer>();
    for(int i=0;i<list1.size();i++){
        ClassroomStatus item=list1.get(i);
        if(!"0".equals(item.getZc())){
            map.put(item.getClassroomName(),1);
        }else{
            Integer tmpMapVal=map.get(item.getClassroomName());
            if(tmpMapVal!=null && tmpMapVal==1){
                list1.remove(item);
                i--;/*这里一定要注意*/
            }else{
                item.setZc(zc);
                item.setXqj(xqj);
                item.setDjdj(djdj);
                item.setClassroomStatus("空闲中");
                list1.set(i,item);
            }
        }
    }
    return list1;
}
  • Mapper层接口 与 sql语句

    • public List<ClassroomStatus> findAllBySevenCondition(String classroomType,String classroomArea,int classroomHold,String zc,int xqj,int djdj,String classroomLevel);
      
      <select id="findAllBySevenCondition" resultType="com.SpringBoot1.entity.ClassroomStatus">
          select * from classroom_status where classroomType=#{classroomType} and classroomName like
          "%"#{classroomArea}"%" and classroomHold>=#{classroomHold} and zc like #{zc} and xqj=#{xqj} and djdj=#{djdj}
          and classroomLevel=#{classroomLevel}
      </select>
      
    • public List<ClassroomStatus> findAllByFourCondition(String classroomType,String classroomArea,int classroomHold,String classroomLevel);
      
      <select id="findAllByFourCondition" resultType="com.SpringBoot1.entity.ClassroomStatus">
          select * from classroom_status where classroomType=#{classroomType} and classroomName like
          "%"#{classroomArea}"%" and classroomHold>=#{classroomHold} and zc="0" and classroomLevel=#{classroomLevel}
      </select>
      

2.2 根据4个主键查询出某个教室的在某个时候的具体状态

  • 参数

(1)教室名称classroomName

(2)星期几xqj

(3)第几大节djdj

(4)周次zc

3. 增加逻辑(增加"被占用"状态)

3.1 Mapper层接口与sql语句

/*通过三个主键查找是否存在这个教室状态,重载,上面那个是为了获取一个教室的状态*/
public ClassroomStatus findStatusByThreeKeyColumns(String classroomName,int xqj,int djdj);
<select id="findStatusByThreeKeyColumns" resultType="com.SpringBoot1.entity.ClassroomStatus">
    select * from classroom_status where classroomName=#{classroomName} and xqj=#{xqj} and
    djdj=#{djdj}
</select>
 /*插入这个教室状态*/
    public int insertIntoClassroomStatus(ClassroomStatus classroomStatus);
<insert id="insertIntoClassroomStatus" >
    insert into classroom_status values
    (#{classroomName},#{zc},#{xqj},#{djdj},#{classroomType},#{classroomLevel},#{classroomStatus},#{classroomHold},#{classroomInfo})
</insert>
/*修改周次*/
public int updateClassroomStatus(ClassroomStatus classroomStatus);
<update id="updateClassroomStatus">
    update classroom_status set classroomStatus=#{classroomStatus},classroomInfo=#{classroomInfo},zc=#{zc} where
    classroomName=#{classroomName} and xqj=#{xqj} and djdj=#{djdj}
</update>

3.2 Service层

关键api:public int saveToClassroomStatus(ClassroomStatus classroomStatus){}

大概逻辑:先执行查询(根据教室名称、星期几、第几大节),如果数据库中没有记录,那么则执行添加操作 ;如果有记录,那么执行修改操作。

在这里插入图片描述

其中:

"在classroom_status表中查询是否存在某教室某时间"被占用"的记录"即为statusDao.findStatusByThreeKeyColumns();

"执行修改操作,将zc字段字符串的某位置设置为’_’ "对应着ZcUtil.getNewZcByOldZc(newZc,oldZc) 。

代码:

public int saveToClassroomStatus(ClassroomStatus classroomStatus){

    ClassroomStatus flag=statusDao.findStatusByThreeKeyColumns(classroomStatus.getClassroomName(),classroomStatus.getXqj(),classroomStatus.getDjdj());

    if(flag==null){
        System.out.println("进入insert");
        classroomStatus.setClassroomStatus("被占用");
        statusDao.insertIntoClassroomStatus(classroomStatus);
        return 0;
    }else{
        System.out.println("进入update");
        String oldZc=flag.getZc();
        String newZc=classroomStatus.getZc();
        newZc= ZcUtil.getNewZcByOldZc(newZc,oldZc);
        classroomStatus.setZc(newZc);
        classroomStatus.setClassroomStatus("被占用");

        statusDao.updateClassroomStatus(classroomStatus);
        return 1;
    }
}

ZcUtil.getNewZcByOldZc(newZc,oldZc)的实现代码:

/**
     * 举例:
     * newZc ____________________1___ 24位
     * oldZc ____________1___________ 24位
     * 期望返回的结果:
     * resZc ____________1_______1___ 24位
     * @param newZc
     * @param oldZc
     * @return
     */
    public static String getNewZcByOldZc(String newZc,String oldZc){
        int i;
        char temp[]=oldZc.toCharArray();
        for(i = 0; i < MAXZC; i ++){ /*MAXZC是类成员变量,MAXZC = 24*/
            if(newZc.charAt(i) == '1'){
                temp[i] = '1';
                break;
            }
        }
//        String ans= Arrays.toString(temp).replaceAll("[\\[\\]\\s,]","");
        String ans = String.valueOf(temp);//上面那句话效果等价于这一句话
        return ans;

    }

4. 修改逻辑(“被占用”->“空闲中”)

4.1 Mapper层与sql

同增加逻辑,即:一是根据三个关键字查询数据库中存在的信息(通过调用findStatusByThreeKeyColumns方法),二是将信息存入数据库中(通过调用updateClassroomStatus方法)。

/*通过三个主键查找是否存在这个教室状态,重载,上面那个是为了获取一个教室的状态*/
public ClassroomStatus findStatusByThreeKeyColumns(String classroomName,int xqj,int djdj);
<select id="findStatusByThreeKeyColumns" resultType="com.SpringBoot1.entity.ClassroomStatus">
    select * from classroom_status where classroomName=#{classroomName} and xqj=#{xqj} and djdj=#{djdj}
</select>
/*修改周次*/
public int updateClassroomStatus(ClassroomStatus classroomStatus);
<update id="updateClassroomStatus">
    update classroom_status set classroomInfo=#{classroomInfo}, zc=#{zc} where
    classroomName=#{classroomName} and xqj=#{xqj} and djdj=#{djdj}
</update>

4.2 Service层

在这里插入图片描述

其中:

"在classroom_status表中查询是否存在某教室某时间"被占用"的记录"即为statusDao.findStatusByThreeKeyColumns();

"执行修改操作,将zc字段字符串的某位置设置为’_’ "对应着ZcUtil.setKongXianZc(newZc,oldZc)。

public int setFreeClassroomStatus(ClassroomStatus classroomStatus){
    ClassroomStatus flag=statusDao.findStatusByThreeKeyColumns(classroomStatus.getClassroomName(),classroomStatus.getXqj(),classroomStatus.getDjdj());
    if(flag==null){
        return 0;
    }else{
        String oldZc=flag.getZc();
        String newZc=classroomStatus.getZc();
        newZc= ZcUtil.setKongXianZc(newZc,oldZc);
        classroomStatus.setZc(newZc);
        return statusDao.updateClassroomStatus(classroomStatus);
    }
}

5. 删除逻辑 ~ 同修改逻辑

删除某个状态,等价于将某个状态置为空闲。

如果某记录的周次字段全为下划线,那么可以将该记录删除掉,通过定位"classroomName" and “xqj” and “djdj”

举报

相关推荐

0 条评论