阅读本文的告示:请一字一句读!请一字一句读!请一字一句读!
对新手而言,写一个解析数独软件,并不简单。
主要原因是因为:数独逻辑并不是线性的,而所有人类就天生只能思考线性的事务。
所以最好使用流程图,梳理清楚流程。
当然需要注意的是!
如不经思考,我画的流程图,本质上来说,对你是没有帮助的!
(这个观点衍生自一个叫YJANGO的人的视频,他在一个分析思维导图的视频中说,如果你不看他的视频,那么画出来的思维导图,对你而言也是没有价值的。)
这个说法其实很值得深思。
例如下面是我画的流程图。
你初看上去,感觉一定是:让我多看几眼,一眼没法看明白。
本质上来说,流程图展现的是你的思考过程。
思考会遇到障碍,你就会想到如何去解决这个障碍。
下面,我用文字和你分解一下我的流程图。
一开始我就设置了一个栈。
这甚至看起来很无厘头。实际上我也是再后来才意识到要用栈来存储数据的,不过最终把这个结论提前到了最前面。
下面请看我的第一版流程:
第一版流程
最开始的时候,其实我先想到的是这个流程:
这个流程中什么细节也都不没有。与其说是流程图,不如说是思维导图。
但其实这版本的里确立了最基础的方法:
不断尝试1-9,成功尝试下一个格子,失败回溯上一个格子。
程序设计有一个警语:不要过早设计细节。
第一版本是一个很成功的版本。确定了最核心的逻辑。
不过很多人可能会说,这个谁想不到呀?不久是硬套么?还说的这么高大上。
不要着急,接下来我们来解决第一版中遇到的问题。
第一版中的问题
问题一:如何判断成功。
答案:如果同宫同列同行均没有矛盾点,即为成功。
(后续可将此设计为一个函数,内含三个检验的小函数)
function isOK {
function hangOK,
function lieOK,
function gongOK
}
问题二:什么时候结束。
答案:如果81个格子都完成了,就有解答。或者回溯到没法回溯了,就没有解。
问题三:如何回溯?
答案:本质上来说,是回到上一个套的位置,然后数字加一,继续套。所以需要记住上一个位置。
因而需要设计一个栈,存储状态,每个状态里存储一个三元组(行标,列标,当前套到了第几个数字)。每次成功进入下一个格子的时候,就入栈。回溯到上一个格子的时候,就取出栈顶元素。
进而设计我们的第二版流程图。
第二版流程
这是我初次绘制的流程。
这个流程,基本上已经正确了,但是主要问题是比较乱。
而且没有符合流程图绘制的规范。
第二版问题
问题一:不好看。
答案:搜索流程图绘制规范,使用合乎要求的图例。
问题二:不具备细节。
答案:进一步完善细节,添加需要的变量。目标是希望具体编写代码的时候,不用进行任何复杂思考。
最终版流程图
至于代码,写起来就很简单了。此处不附。
(完)