题目描述
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在 1960 年 1 月 1 日至 2059 年 12 月 31 日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。
更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如 02/03/04,可能是 2002 年 03 月 04 日、2004 年 02 月 03 日或 2004 年 03 月 02 日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入描述
一个日期,格式是 "AA/BB/CC" (0≤A,B,C≤9)。
输出描述
输出若干个不相同的日期,每个日期一行,格式是 "yyyy-MM-dd"。多个日期按从早到晚排列。
输入输出样例
输入样例
02/03/04
输出样例
2002-03-04
2004-02-03
2004-03-02
思路分析
首先,题目会给我们一个字符串,是以 AA-BB-CC 的格式给出。
题目说了,只有可能有三种日期:
* 年/月/日的格式的,也就是AA为年,BB为月,CC为日
* 月/日/年的格式的,也就是AA为月,BB为日,CC为年
* 日/月/年的格式的,也就是AA为日,BB为月,CC为年
而且,年的话是从1960-2059,也就是说,题目给出的年份只包含后面两位,前面两位是需要我们补充的,比如说后面两位是小于60,那么肯定是20年的,大于等于60,那肯定就是19年的。
再接着是月份和日期,我们需要判断我们拼接的日期是否满足条件,比如说2002年02月29日,这个日期肯定是不合法的,因为2002年不是闰年,2月只能由28天。
同样,2002年02月00日也是不合法的,所以我们需要在拼接日期的时候判读该日期是否合法。在日期合法的前提上再去拼接成字符串。
最后就是日期的去重和排序问题了。
去重的意思是,同样的日期我们只能输出一次。
排序就是,我们根据日期,从小到大进行比较排序。
这种题目难度不是很难,主要是考的细,需要我们注意一点。
AC代码(Java)
题目要求使用升序排序,一些提供排序方法都是默认升序进行排序的,并且字符串的升序是根据字典序进行升序排序的,符合题目要求的按照日期升序排序。
字典序简单提一嘴,就是字符串升序排序,是依次对比每个字符,如果字符相同,就继续比较下一个字符,直到比较出大小。
所以我们直接使用TreeSet即可,这个是去重升序排序的。
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
static Set<String> set = new TreeSet<>(); //存放可能的日期
static int[] date ={0,31,29,31,30,31,30,31,31,30,31,30,31}; //月份表,i代表day1[i]代表月份
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str = scan.next();
scan.close();
//切割出来,分隔成三部分
String[] strs = str.split("/");
//拼凑成日期存放到set中
check(strs);
//打印结果
for(String date : set)
System.out.println(date);
}
//拼凑成日期存放到set中
public static void check(String[] strs){
/* 因为日期可能有三种方法,我们分别处理*/
//第一种是年/月/日的,根据切割字符串来放入,strs[0]代表年份,strs[1]代表月份,strs[2]代表日期
linkDate(strs[0],strs[1],strs[2]);
//第二种是月/日/年的,那么根据strs来放入,strs[0]代表月份,strs[1]代表日期,strs[2]代表年份
linkDate(strs[2],strs[0],strs[1]);
//第二种是日/月/年的,那么根据strs来放入,strs[0]代表日期,strs[1]代表月份,strs[2]代表年份
linkDate(strs[2],strs[1],strs[0]);
}
//拼凑日期
public static void linkDate(String year,String month,String day){
//确定具体年份,最后两年低于60就是20年的,高于等于60就是19年的
year = Integer.parseInt(year) < 60 ? "20"+year : "19"+year;
/* 判断月份是否合法(1-12之间) */
int target = Integer.parseInt(year);
//修改2月的值,如果是闰年就是29天,不然就是28天
date[2] = ((target%4==0&&target%100!=0) || (target%400 == 0)) ? 29 : 28;
//month是月份,转换成整数,然后判断day是否在合法范围内[0-day[month]]
int intMonth = Integer.parseInt(month);
//如果月份不合法(不在1-12之间)
if(intMonth<1 || intMonth>12) return ;
int intDay = Integer.parseInt(day);
//如果不在范围内,直接结束本方法
if(intDay<1 || intDay>date[intMonth]) return ;
/* 年份,月份,日期,都需要满足yyyy-MM-dd,也就是年份4位,月份日期两位*/
if(month.length() < 2) month = 0+month;
if(day.length() < 2) day = 0+day;
/* 都处理好了,放入set中进行去重处理*/
set.add(year+"-"+month+"-"+day);
}
}