现在的位置: 首页 > 综合 > 正文

《编程之美》读书笔记01: 1.2中国象棋将帅问题

2011年02月01日 ⁄ 综合 ⁄ 共 710字 ⁄ 字号 评论关闭

 

  《编程之美》读书笔记01: 1.2中国象棋将帅问题

 

    刚看到题时,首先想到的是除法计算除数的商和余数(eax和edx)。后来才想到C/C++中需要动态多维数组时,new一维数组来模拟多维数组时所进行的多维数组的下标和实际偏移量的转换,我想很多人学习C或C++时都做过这种事吧。

    本以为题目要求输出将帅在棋盘上的具体位置,如d10、f1,但书中的解法给的是相对位置,解决起来更简单。解法一用了一堆令人讨厌的宏,代码实在不美,解法三和解法一本质是一样的,虽然解法三只定义了一个结构体,但结构体内有两个变量,总共有三个变量,不合题意才对。

     要将一个变量i拆成两个,可以根据它的二进制表示分别取出连续几位,比如第0-3位和第4-7位,读变量时,取出变量i相应的几位,存变量时,再更新变量i的对应几位。另外,利用位置的对称性,可以一次输出两个,减少循环次数。

下面的代码和解法一类似,但是一次输出两个,减少了循环次数,并且没有用到除法,如果不考虑C++ IO效率的影响,会比解法二和解法三都高效。

 

  //外层循环变量b使用i的第4-7位,初始值为1,最大值为8。
  //内层循环变量a使用i的第0-3位,初始值为b+1,最大值为9。
  for (unsigned i = 0x10; i < 0x90; i += 0x10)
    for (i= (i & 0xF0) | (i >> 4); (++i & 0xF) < 10; )
      if (((i & 0xF) - (i >> 4)) != 3 && ((i & 0xF) - (i >> 4)) != 6)
        std::cout << "A=" << (i >> 4)  << ", B="<< (i & 0xF) << "\n"
                  << "A=" << (i & 0xF) << ", B="<< (i >> 4)  << "\n";

抱歉!评论已关闭.