作为一个写代码写到半夜的程序员,我经常被朋友问到一些看似简单的问题,21届世界杯是哪一年”,说实话,第一次听到这个问题的时候,我愣了一下——不是我不知道答案,而是我下意识地想用数据结构的方式来思考这个问题,就像在写golang程序时,我们习惯用struct来封装数据,用函数来处理逻辑,世界杯的届数和年份,本质上就是一个键值对的映射关系。
直接答案:21届世界杯的年份
2018年,没错,第21届国际足联世界杯是在2018年举办的,主办国是俄罗斯,那一年夏天,法国队最终捧起了大力神杯,而我在出租屋里对着电脑屏幕,一边调试golang代码,一边看比赛直播。
但如果你以为我只是想告诉你这个年份,那你就错了,作为一个技术写作者,我更想用golang的思维方式,带你把这个“21届世界杯是哪一年”的问题拆解清楚,顺便让你以后遇到类似问题时,自己能快速推导出来。
世界杯届数与年份的“映射表”——就像golang的map
想象一下,如果我们用golang来存储世界杯届数和年份的关系,最简单的方式就是用map[int]int。
worldCupYear := map[int]int{
1: 1930,
2: 1934,
21: 2018,
22: 2022,
}
但这样写有点傻,因为你需要把每一届都手动填进去,世界杯的举办年份是有规律的——每4年一届,除了1942年和1946年因为二战停办了两届,从第一届1930年开始,加4年就是下一届。
让我们手动算一下:第1届是1930年,那么第21届就是1930 + (21-1)*4 = 1930 + 80 = 2010年?等等,这里有个坑,我刚才算出来的是2010年,但第21届实际上是2018年,为什么?因为二战期间停办了两届(第5届和第6届),所以实际举办的届次和年份之间并不是严格的线性关系。
这就是为什么直接用公式算会出错,就像你在golang里写循环时,如果不考虑边界条件和异常情况,程序很容易出bug。
从第1届到第21届:用代码思维遍历一遍
我们来列个表,用golang的for循环思路,把每届世界杯的年份和主办国都过一遍,这样你就能清楚地看到,为什么第21届是2018年。

| 届数 | 年份 | 主办国 | 备注 |
|---|---|---|---|
| 1 | 1930 | 乌拉圭 | 第一届 |
| 2 | 1934 | 意大利 | |
| 3 | 1938 | 法国 | |
| 4 | 1950 | 巴西 | 二战后恢复 |
| 5 | 1954 | 瑞士 | |
| 6 | 1958 | 瑞典 | |
| 7 | 1962 | 智利 | |
| 8 | 1966 | 英格兰 | |
| 9 | 1970 | 墨西哥 | |
| 10 | 1974 | 西德 | |
| 11 | 1978 | 阿根廷 | |
| 12 | 1982 | 西班牙 | |
| 13 | 1986 | 墨西哥 | |
| 14 | 1990 | 意大利 | |
| 15 | 1994 | 美国 | |
| 16 | 1998 | 法国 | |
| 17 | 2002 | 韩国/日本 | |
| 18 | 2006 | 德国 | |
| 19 | 2010 | 南非 | |
| 20 | 2014 | 巴西 | |
| 21 | 2018 | 俄罗斯 | 答案在这 |
| 22 | 2022 | 卡塔尔 |
看到没?从1930年到2018年,这中间有将近90年的跨度,如果你用for i := 1930; i <= 2018; i += 4这样循环,你只会得到 1930, 1934, 1938, 1942... 但1942和1946没有举办,所以实际上循环到1950年的时候,年份和届数就已经对不上了。
关于费曼学习法的额外想法
说到这里,我突然想起来,写这个文章的时候我一直在用费曼写作法——就是那种“用自己的话,把复杂的东西讲给小白听”的方式,费曼说过,如果你不能简单地解释一个概念,说明你还没有真正理解它,当我问我“21届世界杯是哪一年”的时候,最好的回答不是直接甩给你一个年份,而是带你走一遍推导过程,让你自己得出答案。
就像在golang里调试一个bug,最有效的方式不是直接告诉你改哪里,而是带你一起看日志、走读代码,最后你自然会找到问题所在。
为什么不用公式直接算?因为现实世界有异常
说实话,我一开始也想偷懒,直接用 year = 1930 + (n - 1) * 4 这个公式,但现实世界的复杂在于,1942和1946这两届没有举办,所以如果你从第1届开始数,数到第21届,实际上经过了80年(因为少了8年)?让我再算一遍:
- 第1届:1930
- 第2届:1934(+4)
- 第3届:1938(+4)
- 第4届:1950(+12,因为跳过了1942和1946)
- 第5届:1954(+4)
- 以此类推...
这样一来,到第21届的时候,年份已经不是简单的等差数列了,但如果我们用编程的思维,把“是否停办”作为一个条件判断,那就清晰多了。
func getWorldCupYear(n int) (int, bool) {
year := 1930
count := 1
for count < n {
year += 4
// 1942年和1946年停办
if year != 1942 && year != 1946 {
count++
}
}
return year, true
}
运行这个函数,传入21,返回的就是2018,完美。
世界杯届数背后的“数据结构”
其实仔细想想,世界杯的届数和年份之间的关系,很像golang里的slice和index,届数就是index(从1开始),年份就是slice里的元素,但如果你在slice中间删除了两个元素(1942和1946),那么后面所有的index都会偏移,这就是为什么你不能简单地用公式来算。
作为一个经常写代码的人,我特别喜欢这种“看似简单但细节很坑”的问题,它提醒我们,无论处理什么问题,都要先理解背后的逻辑,而不是机械地套公式,就像我们在golang里写并发程序时,如果不理解goroutine和channel的本质,光靠复制粘贴代码,迟早会出大问题。
21届世界杯是哪一年?
2018年,但更重要的是,你现在知道怎么推导出这个答案了,如果你以后遇到这种问题,第25届世界杯是哪一年”,你也可以用同样的方法算出来——只要知道当前最新的一届是2022年(第22届),然后往后推就行了。
第22届:2022年 第23届:2026年(美国、加拿大、墨西哥联合主办) 第24届:2030年(乌拉圭、阿根廷、巴拉圭联合主办) 第25届:2034年(沙特阿拉伯主办)
你看,掌握了方法之后,你可以自己推算出未来几十年的世界杯年份,这比单纯记住一个数字有用多了。
好了,写到这我也该去继续写我的golang代码了,下次如果你遇到类似的问题,不妨也用“编程思维”来推导一下,你会发现很多看似无规律的东西,其实都是结构化的,就像世界杯的届数和年份,本质上就是一个map——只不过这个map里有两个key被删掉了而已。
本文来自作者[kyadmin]投稿,不代表678体育 - 全网热门体育赛事高清直播平台立场,如若转载,请注明出处:http://www.wuxijiangyou.cn/fc/1717.html
评论列表(4条)
我是678体育 - 全网热门体育赛事高清直播平台的签约作者“kyadmin”!
希望本篇文章《21届世界杯是哪一年?让我用golang的思维帮你理清楚》能对你有所帮助!
本站[678体育 - 全网热门体育赛事高清直播平台]内容主要涵盖:678体育,678体育官网,678赛事直播
本文概览:作为一个写代码写到半夜的程序员,我经常被朋友问到一些看似简单的问题,21届世界杯是哪一年”,说实话,第一次听到这个问题的时候,我愣了一下...