题目
《计算机算法设计与分析》第五版2.11
java目录
/**
* Main类
* @author ltc
*
*/
public class Main {
public static void main(String args[]) {
Methods m = new Methods();
int[][] a = null;
m.Table(4, a);
}
}
菜鸡的我也是暑假实训才学会这种,把main和调用方法分到两个.java里,这样以后再写只需要往Methods里添加方法,Main里只多了一行Methods对象创建以及需要注释掉的输入变量声明。比起以前全装在一个文件里轻巧些。
/**
* 被Main.java调用的方法
* @author ltc
*
*/
public class Methods {
public void print(String s){
System.out.println(s);
}
//
public void Table(int k, int a[][]){
int n = 1<<k;
a = new int[n][n];
for(int i = 0; i < n; i++){
a[0][i] = i+1;
}//填第0行
try{
for(int m = 1; m < n; m *= 2){//小块的大小
for(int t = 0; t < n/(2*m); t++){
for(int i = 0; i < m; i++){
for(int j = 0; j < m; j++){
a[m+i][(2*t+1)*m+j] = a[i][2*t*m+j];
a[m+i][2*t*m+j] = a[i][(2*t+1)*m+j];
}
}
}
}
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("here is an exception");
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
System.out.print(a[i][j]+" ");
}System.out.println("");
}
}
System.out.println("here is the answer");
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
System.out.print(a[i][j]+" ");
}System.out.println("");
}
}
}
控制台print
here is the answer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
2 1 4 3 6 5 8 7 10 9 12 11 14 13 16 15
3 4 1 2 7 8 5 6 11 12 9 10 15 16 13 14
4 3 2 1 8 7 6 5 12 11 10 9 16 15 14 13
5 6 7 8 1 2 3 4 13 14 15 16 9 10 11 12
6 5 8 7 2 1 4 3 14 13 16 15 10 9 12 11
7 8 5 6 3 4 1 2 15 16 13 14 11 12 9 10
8 7 6 5 4 3 2 1 16 15 14 13 12 11 10 9
9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8
10 9 12 11 14 13 16 15 2 1 4 3 6 5 8 7
11 12 9 10 15 16 13 14 3 4 1 2 7 8 5 6
12 11 10 9 16 15 14 13 4 3 2 1 8 7 6 5
13 14 15 16 9 10 11 12 5 6 7 8 1 2 3 4
14 13 16 15 10 9 12 11 6 5 8 7 2 1 4 3
15 16 13 14 11 12 9 10 7 8 5 6 3 4 1 2
16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
算法
算法是从书上学的,递归思想迭代实现,直白地说就是先把第0行用从1到2^k填满,然后用这去一行去1生2,2生4,4生8…m生2m…
具体“生”法就是代码ij循环里面,在用t遍历的每个2m×2m区域里把右上m×m抄到左下、同时把左上m×m抄到右下。
难点
可能是我太菜,没看太懂书上的代码,反正数组下标从1开始我就难以接受,而且从算法粗略描述直接到没注释的伪代码,让我有点跟不上,所以写出来跟书上不太一样,自己重新写了,这次学着用try…catch来debug,感觉自己比昨天又强了一点。
中间循环体里的m,n,t参数范围写起来可能有点麻烦,阅读书上代码的时候主要难点就在这里。以后再遇到这种中间参数多的,名字就起得有意义一些,i和j还好,kmn就有些confusing了。