枚举算法经典日期问题详解java

举报
求不脱发 发表于 2022/04/24 19:32:35 2022/04/24
【摘要】 枚举算法是我们在日常中使用到的最多的一个算法,它的核心思想就是:枚举所有的可能。 枚举法的本质就是从所有候选答案中去搜索正确的解。

 目录

枚举算法

日期问题

枚举思想

具体代码



枚举算法

枚举算法是我们在日常中使用到的最多的一个算法,它的核心思想就是:枚举所有的可能。 枚举法的本质就是从所有候选答案中去搜索正确的解。

使用该算法需要满足两个条件:(1)可预先确定候选答案的数量;(2)候选答案的范围在求解之前必须有一个确定的集合。

枚举算法简单粗暴,他暴力的枚举所有可能,尽可能地尝试所有的方法。虽然枚举算法非常暴力,而且速度可能很慢,但确实我们最应该优先考虑的!因为枚举法变成实现最简单,并且得到的结果总是正确的。

日期问题

题目链接http://oj.hzjingma.com/p/7164?view=classic

题目描述

小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在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

2003-03-02

枚举思想

日期问题一般思路都是根据我们的尝试枚举判断日期是否合法等,例如月份1-12,日期1-31或闰年的判断等等。重点在于枚举出所有日期的情况去判断,找出正确答案,避免重复枚举或缺项。

具体代码

package Test;

import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;

public class _日期问题 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String data = scanner.next();
		String[] str = data.split("/");//以字符 ' / ' 分割成字符串数组
		TreeSet<String> ans = new TreeSet<String>();//存放正确答案的集合,利用set集合去重
		// 01/02/03
		//枚举三种情况日/月/年 ,年/月/日,月/日/年
		String case1 = f(str[0], str[1], str[2]);
		String case2 = f(str[2], str[0], str[1]);
		String case3 = f(str[2], str[1], str[0]);
		//如果case字符串合法则加入结果集
		if (case1.length() > 0)
			ans.add(case1);
		if (case2.length() > 0)
			ans.add(case2);
		if (case3.length() > 0)
			ans.add(case3);
		//遍历输出结果
		Iterator<String> iterator = ans.iterator();
		for (String anser : ans) {
			System.out.println(anser);
		}
	}
	/**
	 * 判断是否合法,
	 * @param year
	 * @param month
	 * @param day
	 * @return 空字符串"" 表示不合法
	 */
	private static String f(String year, String month, String day) {
		int _year = Integer.parseInt(year);
		int _month = Integer.parseInt(month);
		int _day = Integer.parseInt(day);
		
		if (_year <= 59)//0-59表示2000年以后,要加上2000
			_year += 2000;
		else			//60-99表示1960 - 1999年,加上1900
			_year += 1900;
		
		if (_month > 12 || _month < 1)//判断月份是否合法  <1或者>12均不合法
			return "";
		
		if (_day > 31 || _day < 1)//判断日期是否合法<1或者>31均不合法
			return "";
		/**
		 * 接下来判断每个月份对应的日期是否合法(前面已经保证月份1-31)
		 * 1,3,5,7,8,10,12每个月固定31天,一定合法
		 * 因此要判断其他月份的时候是否合法
		 */
		if(_month == 2) {
			//闰年>29不合法
			if ((_year % 4 == 0 && _year % 100 != 0) || _year % 400 == 0) {
				if (_day > 29)
					return "";
			}
		}else {
			//其他月份>30不合法
			if (_day > 30)
				return "";
		}
		//月份和日期不足10 要补0
		if (_month < 10) {
			month = "0" + _month;
		}
		if (_day < 10) {
			day = "0" + _day;
		}
		return _year + "-" + month + "-" + day;
	}
}


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。