华为OD机试真题 新系统 2026-07-15 PythonJS 实现【日期格式统一与排序】
2026/7/21 7:25:31 网站建设 项目流程

目录

题目

思路

Code

题目

题目内容:

在日常开发中,用户输入的日期格式五花八门。现需要你编写一个程序,能够识别多种日期格式,将其统一输出为 yyyy-mm-dd 格式,并按日期递增顺序排列。

输入为字符串数组。字符串格式类型中,月和日可能补零也可能不补零。

支持斜杠分隔格式,例如 2022/01/01 或 2022/1/1。

支持横杠分隔格式,例如 2022-01-01 或 2022-1-1。

合法年份范围为 1000 到 2100。

输入可能包含非法格式,非斜杠分隔、非横杠分隔、横杠和斜杠混合的内容均为非法格式,非法格式忽略。

不同格式的输入可能解析为同一日期,相同日期只输出一次。

输入数组长度在 1 到 200 范围内,单个字符串长度不超过 50。

需要判断日期合法性,例如月份不能超过 12,二月平年有 28 天,闰年有 29 天。

年份能被 4 整除且不能被 100 整除,或者能被 400 整除都为闰年,否则都是平年。

输入描述:

输入为一行字符串数组,多个日期字符串用英文逗号分隔。

输出描述:

按日期递增顺序输出字符串数组,每个日期字符串输出 yyyy-mm-dd 格式的日期。月份和日期不足两位补前导零。

若所有输入均非法,则输出仅包含一个元素且元素为 NULL 的字符串数组。

输入判定规则中,包含斜杠时按 yyyy/mm/dd 解析,包含横杠时按 yyyy-mm-dd 解析;混合分隔符会因为字段包含非数字而判为非法。

样例 1

输入:

2022/01/01,2022-1-1,20220101,1640995200,2022/1/1,2022-01-01,2022-12-31,1641081600

输出:

2022-01-01,2022-12-31

说明:

多个输入会解析为 2022-01-01,去重后再和 2022-12-31 一起升序输出。

样例 2

输入:

2021/02/29,2021/02-20

输出:

NULL

说明:

2021 年 2 月没有 29 日,混合分隔符也非法,因此没有合法日期。

样例 3

输入:

1970/1/1

输出:

1970-01-01

说明:

1970/1/1 转换后为 1970-01-01。

思路

整体思路:这道题可以分成解析、校验、去重排序三个部分。

第一步:逐个处理输入中的日期字符串,先判断它使用的是斜杠还是横杠作为分隔符。

如果一个字符串同时包含斜杠和横杠,或者两种分隔符都没有,就不属于题目支持的格式,直接忽略。

第二步:按照确定好的分隔符切分字符串。

合法日期必须刚好切成年、月、日三段;如果不是三段,或者某一段为空、包含非数字字符,就说明这个日期非法。

第三步:把年、月、日转成整数后继续做日期合法性校验。

年份必须在 1000 到 2100 之间,月份必须在 1 到 12 之间,这两个条件先判断,避免后面查询月份天数时出错。

第四步:判断日期天数是否合法。

普通月份可以直接按月份查最大天数,二月需要额外判断闰年:能被 4 整除且不能被 100 整除,或者能被 400 整除,才是闰年。

例如 2024 年 2 月 29 日合法,但 2021 年 2 月 29 日非法。

第五步:把合法日期统一格式化为 yyyy-mm-dd。

月份和日期不足两位时要补前导零,例如 2022/1/1 要转换为 2022-01-01。

第六步:用集合去重。

同一个日期可能有多种写法,例如 2022/1/1 和 2022-01-01,它们最终都表示同一天,只输出一次即可。

第七步:对去重后的日期字符串排序。

yyyy-mm-dd 这种格式的年月日从大到小排列,所以按字符串升序排序时,结果就等价于按真实日期递增排序。

如果最后集合为空,说明没有任何合法日期,按题目要求输出 NULL。

Code

import sys def is_leap(year): # 闰年规则只影响二月的最大天数。 return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 def days_in_month(year, month): days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] if month == 2 and is_leap(year): return 29 return days[month - 1] def parse_date(text): has_slash = "/" in text has_dash = "-" in text # 混合分隔符或没有分隔符都不符合题目支持的格式。 if has_slash == has_dash: return None delimiter = "/" if has_slash else "-" parts = text.split(delimiter) if len(parts) != 3: return None if any(part == "" or not part.isdigit() for part in parts): return None year, month, day = map(int, parts) # 年、月、日逐层校验,避免月份非法时访问天数数组越界。 if year < 1000 or year > 2100: return None if month < 1 or month > 12: return None if day < 1 or day > days_in_month(year, month): return None return f"{year:04d}-{month:02d}-{day:02d}" def main(): text = sys.stdin.read().strip() dates = text.split(",") if text != "" else [""] normalized = set() for item in dates: parsed = parse_date(item.strip()) if parsed is not None: # 集合负责去重,同一天不同写法只保留一次。 normalized.add(parsed) if not normalized: print("NULL") else: print(",".join(sorted(normalized))) if __name__ == "__main__": main()

JS

const fs = require("fs"); const line = fs.readFileSync(0, "utf8").trim(); function isLeap(year) { // 闰年规则只影响二月最大天数。 return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; } function daysInMonth(year, month) { const days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if (month === 2 && isLeap(year)) { return 29; } return days[month - 1]; } function parseDate(text) { const hasSlash = text.includes("/"); const hasDash = text.includes("-"); // 只允许单一分隔符,混用或无分隔符都非法。 if (hasSlash === hasDash) { return null; } const delimiter = hasSlash ? "/" : "-"; const parts = text.split(delimiter); if (parts.length !== 3) { return null; } for (const part of parts) { if (!/^\d+$/.test(part)) { return null; } } const year = Number(parts[0]); const month = Number(parts[1]); const day = Number(parts[2]); // 先校验年月范围,再检查当月最大天数。 if (year < 1000 || year > 2100 || month < 1 || month > 12) { return null; } if (day < 1 || day > daysInMonth(year, month)) { return null; } return `${String(year).padStart(4, "0")}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`; } const seen = new Set(); const items = line === "" ? [""] : line.split(","); for (const item of items) { const parsed = parseDate(item.trim()); if (parsed !== null) { // Set 负责去重,排序在输出前统一处理。 seen.add(parsed); } } if (seen.size === 0) { process.stdout.write("NULL"); } else { process.stdout.write(Array.from(seen).sort().join(",")); }

【华为od机试真题Python+JS+Java+Go合集】【超值优惠】:Py/JS/Java/Go合集

【华为od机试真题Python】:Python真题题库

【华为od机试真题JavaScript】:JavaScript真题题库

【华为od机试真题Java&Go】:Java&Go真题题库

【华为od机试真题C++】:C++真题题库

【华为od机试真题C语言】:C语言真题题库

【华为od面试手撕代码题库】:面试手撕代码题库

【华为od机试面试交流群】【文章底部有二维码链接,可扫码加交流群】

华为OD机试:二本院校有机会吗? 有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询