刷卡考勤管理:每天早上 晚上 进行签到签退,如果未进行正常操作,就需要进行补签,补签只能允许补15天的记录,
被考勤人出站后就无需进行考勤,在极端情况下,被考勤人在15天内既有出站记录又有入站记录的,或者进行多次出站
与入站操作则情况就较为复杂。测试用例如下:
数组A[] int[] temp =new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; 模拟1到15天的考勤记录
下面二位数组 中 {“5”,”1”} 中的5表示第五天,1表示入站 2 表示出站
String[][] date1 = new String[][]{{“5”,”1”},{“11”,”2”}};
这句代码的意思为 当前被考勤人员 第五天入站,第十一天出站离开。
用图表示为
|------------------|
| |
--1--2--3--4--5--6--7--8--9--10--11--12--13--14--15-->
的一个闭区间。
但是如果是
String[][] date2 = new String[][]{{"5","2"},{"11","1"}};
这种情况则 是先出站在入站
--------------| |-------------------
| |
--1--2--3--4--5--6--7--8--9--10--11--12--13--14--15-->
的一个开区间。
String[][] date1 = new String[][]{{"5","1"},{"11","2"}};
String[][] date2 = new String[][]{{"5","2"},{"11","1"}};
String[][] date3 = new String[][]{{"5","2"}};
String[][] date4 = new String[][]{{"5","1"}};
String[][] date5 = new String[][]{{"5","2"},{"9","1"},{"11","2"},{"14","1"}};
String[][] date6 = new String[][]{{"5","1"},{"7","2"},{"10","1"},{"15","2"}};
以上是测试的几种情况。
我的设计思路是:
1. 如果先是入站在是出站则值为一个闭区间,如果先出站在入站则是一个开区间。
2. 开区间不好取值与计算,统一转化为闭区间,遇到开去区间则取闭区间的反即可。
/**
先不管是否为开区间和闭区间,统一算出所有的开区间
*/
private static List<Integer> algorithmSectionAttendance(int[] temp,
String[][] date1) {
int size = date1.length;
int j = 0;
boolean flag = false;
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < temp.length; i++) {
if((temp[i]+"").equals(date1[j][0])){
if(j%2==0){flag =true;}else{flag =false;} //核心算法
j = (j<size-1)?(++j):(j);
}
if(flag == true){//compor(temp[index]+expression+temp[i])
list.add(temp[i]); //System.out.println("temp[index]:"+temp[index]+"temp[i]:"+temp[i]+"j:"+j);
}
}
return list;
}
private static List<Integer> algorithmSectionAttendance(int[] temp,
String[][] date1,String kq){
List<Integer> newList = new ArrayList<Integer>();
for (int tes : temp) {
newList.add(tes);
}
List<Integer> list = algorithmSectionAttendance(temp, date1);
if("1".equals(date1[0][1])){
for (Integer integer : list) {
if(newList.contains(integer))
newList.remove(integer);//取反操作
}
return newList;
}else{
return list;
}
};