编程之美1.2, 题目不再重复了,这里主要研究方法二。
核心思想就是两重循环分别从1到9,如果两个变量处于同一直线则跳过,不然就打印出两个变量。题目的要求在于只能用一个字节来存储,所以就需要空间上进行巧妙的变换。两个变量从1到9,其实只有9*9=81种状态,理论上一个字节存储已经绰绰有余了。
题中方法二给出的解法就是将AB的状态转换为两位9进制的数,低位的数值i%9代表A的状态,高位数值i/9代表B的状态。代码如下:
public static void chess(){
char i=81;
while(i-->0){
if((i/9%3)==(i%9%3)){
continue;
}
System.out.println("a"+(i%9+1)+"b"+(i/9+1));
}
}
由此就由一个字节来代表了两个变量的循环。由此得到启发,还可以继续扩展,比如三重循环四重循环,参考博客。
举个例子
public static void n(){
int counter=0;
for(int i=0; i<5; i++){
for(int j=0; j<4; j++){
for(int k=0; k<3; k++){
System.out.println("counter="+counter+"i="+i+", j="+j+", k="+k);
counter++;
}
}
}
}
这是一个三重循环,三个变量,但是其实一共也只有5*4*3=60中状态,只是求i j k的方法稍有改变。
i=(counter/(3*4))%5
j=(counter/3)%4
k=counter%3
public static void n2(){
int var=5*4*3;
int counter;
for(counter=0; counter<var; counter++){
System.out.println("counter="+counter+"i="+((counter/(3*4))%5)+", j="+((counter/3)%4)+", k="+(counter%3));
}
}
运行后输出的结果完全一样。