荷兰国旗问题程序及运算结果出错分析C语言

下图为编写解决荷兰国旗问题的经典程序(红0白1蓝2):

但是实际运行结果(如下图)并不与预期相符,且只有首位为0时可能出现错误。

下面编者将对原因进行探讨:

Ⅰ.首先分析只有1和0的特殊情况:此时需要分首位为0和首位不为0两种情况。

    一.首位为0(不止首位1个0)时:由于在程序运行过程中,首位元素始终不被next判断,造成实际触发互换机制与首位非0相比少了一次,进而造成某些情况下程序运行结果出错。

下面举几种出错情况:

      1.当首位0和第二个零之间的1多于第二个0之后的0的数量时,程序运行结果必会出错。为了便于理解,可以认为第三个及以上的0起到了替换被夹着的1的作用。

例如:0 1 1 0 0运行结果为0 0 1 0 1;而 0 1 1 1 0 1 0 0 0运行结果为0 0 0 0 0 1 1 1 1。

      2.当第1种错误情况未出现时,依然有可能出现错误情况。

例如:0 1 1 0 1 0 0 0;0 1 0 1 1 1 1 0 0 0 0;

       此种情况出错的原理与第1种一致,可将其视为第1种情况的嵌套。当第二个0后面的0依次与夹着的1互换后,可能会再次出现两0夹1的结构(即第二个0后面的0多于夹着的1),原来的第二个0成为新结构中“第一个”零,此时判断方法与第1种情况类似,即判断两0夹1结构后面的0的个数是否多于结构中1的个数。

     二.首位不为0时:程序结果不会出错。

Ⅱ.接下来分析只有2和1的特殊情况:此时仍然分析首位为2和首位不为2两种情况。

     一.首位为2:由于无0存在首位一直是2,程序必出错。但除首位外,其余部分排列正常。

     二.首位不为2:程序结果不会出错。

Ⅲ.最后分析0、1、2均存在的情况:分为首位为1、首位为0、首位为2三种情况。

     一.首位为1:程序不会出错。

     二.首位为2:程序不会出错。由于有0的存在,首位2会被换到后面,这就避免了Ⅱ(一)型的出错情况,程序也就不会出错。

    三.首位为0:程序可能出错。经过大量试验可以发现,程序最终结果中2总在最后。那么我们可以套用Ⅰ型错误情况进行分析。

      1.一组两0夹1:当只存在首位0和第二个0组成的两0夹1结构时,后面的1与2等价,不会影响结果,判断方法与Ⅰ(一)一致。

      2.一组两0夹2:当只存在首位0和第二个0组成的两0夹2结构时,next读取到2就会触发后调机制将2向末尾调。若换回来的是1,程序继续执行,无变化;若换回来的是0,触发前调机制将0向前移动,换回来的必是1,相当于最后面的0先替换两0所夹元素而非排序较前的0。判断方法仍与Ⅰ(一)一致。

      2.一组两0夹1、2:当next读取到两0所夹1时,无变化。当next读取到两0所夹2时,触发后调机制将2向后移动,若换回来的是1,程序继续执行,无变化;若换回来的是0,触发前调机制将0向前移动,换回来的必是1,相当于最后面的0先替换两0所夹元素而非排序较前的0。综上,我们依然可以通过Ⅰ(一)的方法进行判断。

     3.多组两0夹1、2:此时原理及判断方法与Ⅰ(2)完全一致,此处不再赘述,建议读者自行思考检验理解程度。

现在关于荷兰国旗问题运行出错的分析到此结束,总而言之,是程序设计存在漏洞,进而导致对于一些特殊数据无法得出正确结果。

本人学识有限,如有错误之处还望指正。

    

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值