编程之美之将帅问题学习笔记
书中的第一种解法很容易理解,这里就不赘述,但是第二种算法百思不得其解。if((i / 9) % 3 == (i % 9) % 3) 是个什么意思。。。。。百度了不少资料,发现正解很少。。
让我恍然大悟的链接 https://book.douban.com/annotation/13753057/,所以这里Mark一记
这里的取模运算到底是个什么意思?????黑人问号
通常情况下来说,我用到取模运算的地方就是负载均衡的时候,通过一个独立的UUID进行取模,然后分配到指定的服务器上,例如我的UUID=1,小明的UUID=8,但是我只有两组服务器,如何保证我每次进来的时候分配的服务器是同一台呢。这里就用到了取模 %2即可。
“可以把变量i想象成一个两位九进制的变量,而i在计算机中存储的值是i的十进制表示。则i/9的计算机处理结果,即结果直接去掉小数点后部分的结果即是此九进制数的第二位,而i%9即是此九进制数的个位。本程序用此九进制数的第二位保存A的位置,个位表示B的位置。最大值为88,即为十进制的80.程序从十进制的80,即九进制的88遍历到十进制的0,即九进制的0.将符合条件的位置全部输出。” 引用 https://book.douban.com/annotation/13753057/
书中的这种解法只用了一个数去存储两个将帅出现的位置,这里采用了9进制存储,其中两位是分别存储不同将帅的位置。
这里2位存储9进制的最大值为88,换算成10进制为80,循环到10进制的0,总共有81种情况。
假设第一位存储将帅A可能出现的位置,第二位存储将帅B可能出现的位置
这里的除9表示取第二个将帅的位置,学到了,(例如 99/10 /10=取十位的数字9, %10=个位数字9)小学除法的含义都还给老师了。。。惭愧。。。。。。。。。。
模3比较好理解,就是取将帅出现的第几列,因为总共只有三列所以就是模3了。
因为while先会执行 i--, 这里将i的初值设为81
BYTE i = 81; while(i--) { if((i / 9) % 3 == (i % 9) % 3) continue; printf("A = %d, B = %d\n", i /9 + 1, i%9 + 1); } return 0;
我这里用php写了一份,个人觉得更好理解一些吧
因为开始最大值为88,其实到00也会需要执行,这里用了intval而不能用round是因为,round是四舍五入,intval不会。
round(3.6) = 4
intval(3.3) = 3
<?php $i = 80; while ($i >= 0) { if (intval(intval(($i / 9)) % 3) != intval(intval(($i % 9)) % 3)) { var_dump('A:' . (intval(($i / 9)) + 1), 'B:' . (intval(($i % 9)) + 1)); } $i--; } ?>