今天是人生中第一次開車上班,想要感受下廣州的開車上下班的感覺,開車上班後,因爲開的車是東莞的牌,廣州實行開四停四的政策,然後就要想着自己開了幾天明天是否還可以開,然後做一個程序猿,很職業的想到這樣一個問題,如果交通管理系統是我做的,如果拍到今天開車了,系統後臺是如何實現計算開四停四違法了呢?
首先要理解的是廣州這個“開四停四”這個管理措施,官方描述:即非廣州市籍中小客車駛入廣州市中心區連續行駛時間最長不得超過4天,再次駛入須間隔4天以上,例子如下圖:
一開始的時候就在要找到哪天開始開的,累計開了多少天,但這政策是不存在類似月初清0的沒有開頭,什麼隔天開,如果按照這種思路有點複雜,後面換一個思路.
想了一下發現要實現這個算法,關鍵是找到連續停的四天,如果八天裏存在一個連續停的四天,那說明本次開車是合法的,爲什麼是八天呢,因爲是開的四天+停的四天,不管這八天裏這開的四天是怎麼開的,是連續四天還是隔着開的四天,停的天數它必須是連續的.
所以關鍵判斷是否存在連續停的四天就可以了
package com.jim.java8;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
/**
* 限行違法計算
*
* @author Jim
* @date 2019/2/26
*/
public class ComputeRestrict {
/**
* 開車記錄
*/
List<String> driverRows = new ArrayList<>();
public ComputeRestrict() {
initDemoDriveData();
}
/**
* 初始化開車記錄
*/
private void initDemoDriveData() {
driverRows.add("2019-02-01");
driverRows.add("2019-02-07");
driverRows.add("2019-02-08");
driverRows.add("2019-02-09");
}
/**
* 是否違法
*
* @param localDate
* @return
*/
private boolean isIllegal(LocalDate localDate) {
return !hasContinuousNotDrive4Day(localDate, 8, 0);
}
/**
* 是否存在連續停的四天
* 判斷某天是否
*
* @param fromDate 開始計算時間
* @param leftDays 餘下天數
* @param notDriveDays 累計停的天數
* @return true/存在
*/
private boolean hasContinuousNotDrive4Day(LocalDate fromDate, int leftDays, int notDriveDays) {
for (int i = 1; i < leftDays; i++) {
LocalDate localDate = fromDate.plusDays(-i);
if (isNotDrive(localDate)) {
++notDriveDays;
if (notDriveDays >= 4) {
return true;
}
} else {
if ((leftDays - i) >= 4) {
return false;
} else {
return hasContinuousNotDrive4Day(localDate, leftDays - i, 0);
}
}
}
return false;
}
private boolean isNotDrive(LocalDate tempDate) {
return !driverRows.contains(tempDate.toString());
}
public static void main(String[] args) {
LocalDate localDate = LocalDate.parse("2019-02-14");
System.out.println("本次開車是否違法:" + new ComputeRestrict().isIllegal(localDate));
}
}
如上面代碼所示核心的代碼爲使用遞歸判斷是否連續停了四天方法"hasContinuousNotDrive4Day"
以上爲個人想法,歡迎指正!!