go语言:实现doomsday末日算法(附带源码)

一、项目背景详细介绍

在计算机科学与数学领域中,有一类非常有意思、也非常“优雅”的算法:心算友好型算法。它们不依赖复杂计算,却能通过规律和结构,快速得到结果。

Doomsday Algorithm(末日算法),正是其中最著名的代表之一。

该算法由传奇计算机科学家 John Horton Conway 提出,用于:

快速计算任意日期是星期几

末日算法的特点是:

  • 规则清晰、可解释性强
  • 既适合人脑心算,也非常适合程序实现
  • 是算法思维、数学建模、时间系统理解的绝佳案例

在工程实践中,虽然我们可以直接调用标准库,但:

  • 面试中经常考察「日期算法原理」
  • 算法课程中用于训练建模能力
  • 自实现有助于理解历法、闰年、模运算

因此,本文将使用 Go 语言,完整实现一套可教学、可运行、可验证的 Doomsday 末日算法。


二、项目需求详细介绍

2.1 功能性需求

  1. 输入任意合法日期(年、月、日)
  2. 输出该日期对应的星期
  3. 支持公历(Gregorian Calendar)
  4. 正确处理闰年规则
  5. 提供完整示例可直接运行

2.2 非功能性需求

  1. 不依赖 time 包的 Weekday 计算
  2. 算法步骤清晰、易于讲解
  3. 适合博客、课堂、面试讲解
  4. 所有代码放在单一代码块中

三、相关技术详细介绍

3.1 什么是 Doomsday(末日)

在 Doomsday 算法中,**Doomsday(末日)**指的是:

某一年中,一组“固定日期”都落在同一个星期几

例如(非闰年):

  • 4 月 4 日
  • 6 月 6 日
  • 8 月 8 日
  • 10 月 10 日
  • 12 月 12 日

它们在同一年中,星期几是完全一致的。

3.2 年锚点(Century Anchor Day)

每个世纪都有一个固定的“锚点星期”,例如:

  • 1900–1999:星期三
  • 2000–2099:星期二

这是算法中非常关键的一步。

3.3 闰年规则说明

公历闰年规则:

  1. 能被 400 整除 → 闰年
  2. 能被 100 整除但不能被 400 整除 → 平年
  3. 能被 4 整除但不能被 100 整除 → 闰年

四、实现思路详细介绍

4.1 算法总体流程

  1. 计算世纪锚点星期
  2. 计算当年 Doomsday 星期
  3. 找到该月的 Doomsday 日期
  4. 根据日期差值推算目标星期

4.2 月份 Doomsday 对照表

月份平年闰年
11月3日1月4日
22月28日2月29日
33月14日3月14日
44月4日4月4日
55月9日5月9日
66月6日6月6日
77月11日7月11日
88月8日8月8日
99月5日9月5日
1010月10日10月10日
1111月7日11月7日
1212月12日12月12日

五、完整实现代码

说明:以下所有代码放在一个代码块中,不同文件使用注释区分,可直接运行。
// ========================================= // 文件:doomsday.go // 描述:Go语言实现 Doomsday 末日算法 // ========================================= package main import "fmt" var weekdays = []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"} // IsLeapYear 判断是否为闰年 func IsLeapYear(year int) bool { if year%400 == 0 { return true } if year%100 == 0 { return false } return year%4 == 0 } // GetCenturyAnchor 获取世纪锚点(0=Sunday) func GetCenturyAnchor(year int) int { century := year / 100 // Conway 公式:(5 * (century % 4) + 2) % 7 return (5*(century%4) + 2) % 7 } // GetYearDoomsday 计算某一年的 Doomsday func GetYearDoomsday(year int) int { anchor := GetCenturyAnchor(year) y := year % 100 a := y / 12 b := y % 12 c := b / 4 return (anchor + a + b + c) % 7 } // GetMonthDoomsday 获取某月的 Doomsday 日期 func GetMonthDoomsday(month int, leap bool) int { doomsdays := [][]int{ {3, 4}, // Jan {28, 29}, // Feb {14, 14}, // Mar {4, 4}, // Apr {9, 9}, // May {6, 6}, // Jun {11, 11}, // Jul {8, 8}, // Aug {5, 5}, // Sep {10, 10}, // Oct {7, 7}, // Nov {12, 12}, // Dec } if leap { return doomsdays[month-1][1] } return doomsdays[month-1][0] } // DayOfWeek 使用 Doomsday 算法计算星期 func DayOfWeek(year, month, day int) string { doomsday := GetYearDoomsday(year) leap := IsLeapYear(year) monthDoomsday := GetMonthDoomsday(month, leap) diff := day - monthDoomsday weekday := (doomsday + diff%7 + 7) % 7 return weekdays[weekday] } func main() { year, month, day := 2024, 10, 1 fmt.Printf("%d-%02d-%02d is %s\n", year, month, day, DayOfWeek(year, month, day)) } 

六、代码详细解读(仅解读方法作用)

6.1 IsLeapYear

判断给定年份是否为公历闰年。

6.2 GetCenturyAnchor

计算世纪对应的锚点星期,是 Doomsday 算法的基础。

6.3 GetYearDoomsday

根据年份后两位,推算该年的 Doomsday 星期。

6.4 GetMonthDoomsday

返回指定月份对应的 Doomsday 日期。

6.5 DayOfWeek

综合 Doomsday 算法的所有步骤,计算目标日期的星期。


七、项目详细总结

Doomsday 末日算法是一种:

  • 数学结构优美
  • 规则高度总结
  • 非常适合教学与面试讲解

的经典算法。

通过 Go 语言实现后,可以清晰看到:

  • 时间系统的规律
  • 模运算在工程中的应用
  • 算法思想如何落地为代码

八、项目常见问题及解答

Q1:为什么不直接用 time.Weekday?
A:为了理解算法原理,而不是依赖库。

Q2:算法支持 1582 年之前吗?
A:本文实现基于公历,适用于现代日期。

Q3:结果如何验证?
A:可与标准库 time 包对照测试。


九、扩展方向与性能优化

  1. 支持历史历法(儒略历)
  2. 命令行日期查询工具
  3. 与 time 包结果对照测试
  4. 心算口诀与代码映射总结
  5. 封装为日期算法工具库

至此,一个教学级、算法级、可运行的 Go 语言 Doomsday 末日算法实现已经完整完成。

Read more

Rokid 手势识别技术深度解析:解锁 AR 无接触交互的核心秘密

Rokid 手势识别技术深度解析:解锁 AR 无接触交互的核心秘密

引言 在聊手势识别前,咱们先搞清楚:Rokid是谁?它为啥能把AR手势做得这么自然? Rokid是国内AR(增强现实)领域的“老兵”了,从2014年成立就盯着一个目标——让AR走进日常。你可能见过它的产品:能戴在脸上的“AR眼镜”Max Pro、能揣在兜里的“AR主机”Station 2、适合专业场景的“Station Pro”,这些设备不是用来“炫技”的,而是想让咱们摆脱手机、手柄的束缚,直接用手“摸”虚拟东西。 而手势识别,就是Rokid给AR设备装的“最自然的遥控器”——比如调大虚拟屏幕像捏橡皮一样捏合手指,翻页像翻书一样挥手。但不同设备、不同开发需求,需要搭配不同版本的SDK(软件开发工具包),这就像“不同型号的手机要装对应版本的APP”。 一、基础认知:先选对版本,避免开发走弯路 Rokid手势识别技术随SDK版本迭代持续优化,不同版本适配的Unity(开发工具)

By Ne0inhk
Java 大视界 -- Java 大数据在智能家居能源消耗趋势预测与节能策略优化中的应用(433)

Java 大视界 -- Java 大数据在智能家居能源消耗趋势预测与节能策略优化中的应用(433)

Java 大视界 -- Java 大数据在智能家居能源消耗趋势预测与节能策略优化中的应用(433) * 引言: * 正文: * 一、智能家居能源管理的核心痛点与 Java 大数据的价值 * 1.1 行业核心痛点(基于《2024 中国智能家居行业白皮书》) * 1.2 Java 大数据的核心价值(实战验证适配性) * 二、技术架构设计实战(纵向架构图) * 2.1 核心技术栈选型(生产压测验证版) * 2.2 关键技术亮点(博主实战总结) * 三、核心场景实战(附完整可运行代码) * 3.1 场景一:能耗趋势预测(线性回归 + LSTM 融合模型) * 3.1.1 业务需求 * 3.1.

By Ne0inhk
必收藏!小白也能懂:Agent、Skills、MCP和A2A大模型架构完全指南

必收藏!小白也能懂:Agent、Skills、MCP和A2A大模型架构完全指南

文章详解AI Agent四大核心概念:Agent作为智能决策主体,Skills提供原子化能力封装,MCP实现标准化工具调用,A2A支持Agent间协作。这些技术共同构建了从单Agent自主执行到多Agent协同工作的完整技术栈,解决了智能体的自主性、模块化能力、工具调用和互操作等核心问题,助力开发者快速构建专业级AI应用。 一、Agent、Skills、MCP和A2A的核心概念总览 1、Agent (代理/智能体):自主决策与执行的“大脑”。 AI Agent是2026年AI生态的核心概念,是基于人工智能技术构建的、具备感知环境、理解信息、自主推理决策、自主规划与执行动作并持续与环境/其他主体交互,以自主达成预设或动态生成目标的数字智能实体。2026年的智能体不是在回答问题,而是在完成任务。其突破了传统问答式、生成式AI的能力边界,可像人类员工一样独立处理复杂综合性任务。它以大模型为核心引擎,整合规划、记忆、工具调用与行动执行四大能力,形成「感知 - 认知 - 决策 - 执行 - 反馈」的完整智能闭环,

By Ne0inhk
Kafka架构:构建高吞吐量分布式消息系统的艺术

Kafka架构:构建高吞吐量分布式消息系统的艺术

目录 * Kafka架构:构建高吞吐量分布式消息系统的艺术 * 引言:探索Kafka的宇宙 * Kafka核心概念与架构总览 * 什么是Kafka? * Kafka的核心架构组件 * Kafka的数据模型 * ZooKeeper在Kafka架构中的关键作用 * ZooKeeper的核心职责 * ZooKeeper的数据结构 * ZooKeeper集群配置 * Controller机制 * Kafka的分区与复制机制 * 分区策略 * 自定义分区器 * 复制机制与ISR * 分区分配策略 * Kafka的存储机制 * 日志存储结构 * 高效的存储设计 * 日志清理策略 * Kafka的消费模型 * 消费者组与重平衡 * ZooKeeper在消费者协调中的作用 * 消费者实现 * Kafka性能调优与最佳实践 * ZooKeeper性能优化 * Bro

By Ne0inhk