只使用一个short变量,打印出象棋所有将帅的合法位置
在实际的软件环境中,可能包含m*n个变量。在这么大的变量下,节省一点空间都是好的。这里,主要从象棋的将帅问题入手。通过对这个问题的实现,希望能够从中领会到节省空间的一些办法。将帅问题的解应该是最简单的处理方法了,我们就是要从简单的入手从而掌握整个问题解决的手段。
首先,象棋的将帅问题是我在《《编程之美》》中看到的,里面的解法实在太繁琐。我记得光是#define就有一大堆,反正我是不喜欢看这些东西。下面,希望我这个代码能够简单明了。
将帅问题就是将和帅不能处在同一个竖线上,在正式讨论之前,提供一下正常的判断将帅位置是否合法的方法:
typedef struct stLoc
{
int x;
int y;
} Location;
bool checkValidKingLocation(Location loc1, Location loc2 )
{
if(loc1.y == loc2.y)
{
return false;
}
return true;
}
可以看出,我们需要两个位置变量。每个变量的大小为两个int,如果不使用int,使用CHAR.在考虑4字节对齐的情况下,size并没有改变。所以我们要16字节大小。
如果我们使用一个short型,或者可以直接使用char型。显然我们能够节省很多空间,虽然对于这个例子来说没有什么意义。那么要想这样实现,我们必须让将和帅两个位置在变量之中完全相互独立。将和帅可以分别使用变量中的4个bit来标识自己,说起来很简单。下面就看看实际如何利用代码实现了:
#define IsLowValid(i) ( (i&0xf) < 9 )
#define IsHighValid(i) (((i&0xf0)>>4) < 9)
#define GetLow(i) (i&0xf)
#define GetHigh(i) ((i&0xf0)>>4)
#define ClearLow(i) (i = i & 0xf0)
void printValidLoc()
{
short i =0;
while(IsHighValid(i))
{
while(IsLowValid(i))
{
if(GetHigh(i)%3 != GetLow(i)%3)
{
printf("Red(%d %d) Black(%d %d)\r\n",GetHigh(i)/3,GetHigh(i)%3,GetLow(i)/3,GetLow(i)%3);
}
i++;
}
ClearLow(i);//必须清除低位字符,否则后面的算法错误
i += 16;
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
printValidLoc();
return 0;
}
运行后打印信息如下:
Red(0 0) Black(0 1)
Red(0 0) Black(0 2)
Red(0 0) Black(1 1)
Red(0 0) Black(1 2)
Red(0 0) Black(2 1)
Red(0 0) Black(2 2)
Red(0 1) Black(0 0)
Red(0 1) Black(0 2)
Red(0 1) Black(1 0)
Red(0 1) Black(1 2)
Red(0 1) Black(2 0)
Red(0 1) Black(2 2)
Red(0 2) Black(0 0)
Red(0 2) Black(0 1)
Red(0 2) Black(1 0)
Red(0 2) Black(1 1)
Red(0 2) Black(2 0)
Red(0 2) Black(2 1)
Red(1 0) Black(0 1)
Red(1 0) Black(0 2)
Red(1 0) Black(1 1)
Red(1 0) Black(1 2)
Red(1 0) Black(2 1)
Red(1 0) Black(2 2)
Red(1 1) Black(0 0)
Red(1 1) Black(0 2)
Red(1 1) Black(1 0)
Red(1 1) Black(1 2)
Red(1 1) Black(2 0)
Red(1 1) Black(2 2)
Red(1 2) Black(0 0)
Red(1 2) Black(0 1)
Red(1 2) Black(1 0)
Red(1 2) Black(1 1)
Red(1 2) Black(2 0)
Red(1 2) Black(2 1)
Red(2 0) Black(0 1)
Red(2 0) Black(0 2)
Red(2 0) Black(1 1)
Red(2 0) Black(1 2)
Red(2 0) Black(2 1)
Red(2 0) Black(2 2)
Red(2 1) Black(0 0)
Red(2 1) Black(0 2)
Red(2 1) Black(1 0)
Red(2 1) Black(1 2)
Red(2 1) Black(2 0)
Red(2 1) Black(2 2)
Red(2 2) Black(0 0)
Red(2 2) Black(0 1)
Red(2 2) Black(1 0)
Red(2 2) Black(1 1)
Red(2 2) Black(2 0)
Red(2 2) Black(2 1)
请按任意键继续. . .
转载于:https://my.oschina.net/u/2245760/blog/323723
- 点赞
- 收藏
- 分享
- 文章举报
- 只使用一个short变量,打印出象棋所有将帅的合法位置
- 使用递归法打印出一个目录里的所有文件
- logback框架使用误区 如何将所有包的ERROR级别日志集中打印到一个日志文件中
- 使用反射打印一个类的所有信息
- Java使用Array相关的API,将一个随机字符串中的所有字符升序排列。并倒序打印
- 纯JS实现在一个字符串b中查找另一个字符串a出现的所有位置,并且不使用字符串的方法(递归)
- 有趣编程 打印象棋中两个老帅不碰面的所有位置组合
- 练习2-1 编写一个程序一确定分别由signed及unsigned限定的char,short,int及long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现。通过直接计算来确定浮点类型的取值范围是一项难度很大的任务。
- 只用一个字节 计算象棋将帅之间可能的位置
- (1.5.1.2)编程之美:中国象棋将帅问题——一个变量实现多重循环
- Java反射学习-使用反射修改一个类中的所有String类型的成员变量的值
- 使用递归打印出一个文件夹下所有子孙文件的树形结构
- 打印大X 小明希望用星号拼凑,打印出一个大X,他要求能够控制笔画的宽度和整个字的高度。 为了便于比对空格,所有的空白位置都以句点符来代替。 要求输入两个整数m n,表示笔的宽度,X的高度。用空格分
- 编写一个程序以确定分别由signed及unsigned限定的char、short、int及long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现
- (本程序功能:字符串A中找出包含字符串B中所有字符的位置并输出) 在使用全局变量m的时候,输出错误的结果,而用下面局部变量M就没问题。
- 有一个X*Y的网格,只能向右、向下移动,从(0, 0)走到(X-1, Y-1),中间某些位置有障碍物,打印所有可能的路径
- 使用Aspect中的annotation标签的方法来截获所有的Exception,进行控制台打印
- 实用函数:在一行中打印一个表或视图的所有列,用逗号隔开(SQLSERVER)
- MySQL查询所有供应商和其任意一个产品 - Group by的使用
- 打印出所有的“水仙花数”........(题目不难,注意表示出一个数的个位,十位,百位==的简便方法)