【原创】数独C语言全解-连载2-程序主要原理说明

本文介绍了如何使用指针和三维数组建立一个解数独问题的程序。作者通过建立一个包含9*9*9个指针的结构,实现了回溯功能,以便在找不到解决方案时能退回上一步。方法中,指针用于跟踪空值和数值,第三维用于表示1-9的数字。在搜索过程中,从1开始尝试填充每个空值,若不满足条件则回溯,直至找到正确解。
摘要由CSDN通过智能技术生成

接下来我会在后面的帖子里说明主要的过程。

2021年12月我编写过一个日历拼图的程序,当时也在网站上写了帖子。这次想解数独时,我想使用那里面的方法,那个的内容比较复杂,程序代码也复杂一些,涉及到日历的各种旋转和翻面,不过,过程比较短,才8个广场。

数独的过程会长一些,但处理会简单一些(只有1-9的数字)。

考虑到数独的特点,使用了一个不算高效但是有效的方式,使用9*9*9个指针,用合适的方式串起来,并且能够回溯。(也许有人会问不是用指针的二维数组就可以了吗?怎么要用三维?这就是我刚才说的,有效但不算高效的意思了。用三维指针数组是一个有效的方式,用二维应该也能实现,但我没采用,因为三维会比较直观,稍后就明白了。)

可能有初学者会问(高手请略过),为什么要用指针,用数组来穷举不可以吗?数组穷举是否可以,我不确定,但我以前在用数组来穷举时,就会遇到无法回溯的问题。但指针就可以回溯,从而找到合适的方式。初学者需要先补充一些关于指针、数据结构方面的基本操作。比如,建立数据结构、定义指针,指针空间的申请,指针的各种关联。其中,数据结构可以认为是C语言甚至是所有语言的高级运用的基础工具,是需要掌握的。

以下是我在解数独问题时关于建立指针体系的具体做法。

先建立头指针head,再建立tmp指针(移动指针、或者称为临时指针)。我先判断是否为空值(在程序里以0表示),如果是0就建立指针。对于第一个空值,就将它设为head的下一指针,也就是head->next=第一个空值的指针,同时第一个空值指针的pre指针也就是head。比如,在本例中,(1,1)的值是空的,所以,第一个指针就是(1,1)坐标的。具体内容是head->next=p[0][0][0](第三维的作用稍后解释)还要设置p[0][0][0]->pre=head,是否有这个必要,其实也是有的。这是用来判断程序无解的重要部分。

然后,再找下一个空值。在本例中,(1,2)是空值,所以,p[0][0][0]->next=p[0][1][0],还有p[0][1][0]->pre=p[0][0][0],以此类推。如下图所示。

 

最后一个空值的next指针指向NULL,这是判断数独是否解题结束的主要标志。最后一个空值不是哪个指针的pre。

注:那些已经有数的空格,只是摆设,并不会出现在这个指针体系里面,也不会为他们申请结构空间。

这是主线。

接着说明第三维的作用。第三维,其实是用来表示1-9个数值的。

这9个数值是用left和right串起来的。就是1的left是空指针,而right是2,2的left是1,2的right是3。具体的是p[0][0][0]->left-NULL, p[0][0][0]->right=p[0][0][1], p[0][0][1]->left=p[0][0][0],p[0][0][1]->right=p[0][0][2]。

要注意,目前只有p[i][j][0]有next和pre,其余的不设next和pre(默认为NULL或随机值)。

所以,在主线里,只有p[i][j][0]。这是为了方便搜索时是从1开始到9,如下图所示:

指针体系建立之后,开始进行数独的解的搜索。

先是从第一个空值(比如本例的p[0][0][0])开始。从1-9进行搜索,有合适的数值时,就修改head的next数值为这个。比如这次1是可以的。所以,不需要修改什么内容,直接就可以到下一个空值了。

本例中下一个空值是p[0][1][0],从1开始搜索,明显1是不可以了(和前面的1重复了),所以,要数到2。这时候,需要做一些处理。就是上一个指针的next要指向第2个值,本例中是p[0][0][0]->next=p[0][1][1](之前是p[0][1][0]),而相应的p[0][1][1]->pre= p[0][0][0]。因为2是满足要求的。所以,就到第3个空值了。

第3个空值是(1,3),从p[0][2][0]表示的1开始寻找,明显1、2都是不满足要求的,要算到3,这时候,next和pre也要相应处理。

……

如果到了一个空值,比如(i,j),从1-9都尝试过了(right指针指向NULL了),都无法得到满足要求,这时候,就要回溯到上一个空值,要让上一个空值做出变化,但这时候,指针体系要将上一指针体系的next从现在的9调回到1(这步很关键,不然会导致下一次搜索时,不是从1开始,从而不能把1-9全部搜索一点)。

如果上一层也已经搜索到了9,那就要继续向上一层回溯。注意,此时一样要把指针体系的next定位到第1个数值,不然没办法从1开始搜索,可能会导致出错(我在多次回溯时吃过亏,因为无法解决一些数独,从而导致花费多了一天时间进行查找原因)。

按上述的方法执行时,最终就可以出来正确的解答了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值