使用复数存储网格坐标有哪些技术优势?
使用复数存储网格坐标的实用价值?
你在查看Advent of Code 2022第12题的解决方案时,发现了用复数存储网格坐标的实现:
heightmap = { complex(x, y): c for y, ln in enumerate(sys.stdin.read().strip().split("\n")) for x, c in enumerate(ln) }
后续通过复数加减快速遍历相邻坐标:
for xy, c in heightmap.items(): for d in (1, -1, 1j, -1j): if ord(heightmap.get(xy + d, "{")) <= ord(c) + 1: G.add_edge(xy, xy + d)
你能看出这种写法简化了相邻坐标的获取逻辑,但不确定是否值得额外的理解成本,以下是这种方式的实用价值:
- 极简的邻域坐标计算:复数的加减运算天然对应网格的平移操作,
1/-1对应x轴左右移动,1j/-1j对应y轴上下移动,不用再写(x+1,y)、(x,y-1)这类拆分坐标的冗余代码,一行循环就能遍历四个方向,代码更紧凑直观。 - 统一的坐标存储与传递:用单个复数替代
(x,y)元组,不管是作为字典的键、图的节点还是函数参数,都只用一个值传递,省去了频繁拆包、打包元组的操作,Python对复数的哈希、相等判断支持完善,可靠性和元组一致。 - 极低的额外理解成本(对熟悉复数的开发者):只要理解复数的实部对应x坐标、虚部对应y坐标,这种写法几乎没有学习门槛。需要提取原始坐标时,直接通过
int(xy.real)和int(xy.imag)就能拿到x、y值,操作简单。 - 场景扩展性更强:如果遇到需要坐标旋转、镜像、斜向移动的场景,复数的乘法、共轭等操作能直接实现这些变换。比如乘以
1j就是逆时针旋转90度,取共轭就是x轴镜像,比手动计算元组坐标要高效得多。
至于是否值得用,取决于场景:在Advent of Code这种快速解题的场景下,这种写法能节省编码时间,代码更简洁;如果是团队协作项目,需要考虑其他成员对这种写法的接受度,避免维护成本。但对于个人刷题或小型项目,这种写法的收益远大于所谓的“复杂度”。
内容的提问来源于stack exchange,提问作者outis
相关产品推荐
相关产品推荐

