1.数组乱序
天天搞排序,今天遇到一道乱序的问题居然无从下手,知道random,然后想了很复杂的if条件判断。
其实,只要在数组里面依次拿出一个数,然后产生数组长度范围内的一个数作为下标,然后互换即可!
public class RandomNumber { public static void main(String[] args) { int change = 6; int[] sequence = new int[change]; for (int i = 0; i < change; i++) { sequence[i] = i; } Random random = new Random(); for (int i = 0; i < change; i++) { int j = random.nextInt(change); int tmp = sequence[i]; sequence[i] = sequence[j]; sequence[j] = tmp; } for (int k : sequence) { System.out.println(k); } } }
2.迷宫问题
对于走迷宫,人们提出过很多计算机上的解法。深度优先搜索、广度优先搜索是使用最广的方法。生活中,人们更愿意使用“紧贴墙壁,靠右行走”的简单规则。
下面的代码则采用了另一种不同的解法。它把走迷宫的过程比做“染色过程”。假设入口点被染为红色,它的颜色会“传染”给与它相邻的可走的单元。这个过程不断进行下去,如果最终出口点被染色,则迷宫有解。
package newExam; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class Maze { class Cell { private int row; private int col; private Cell from; public Cell(int row, int col, Cell from) { this.row = row; this.col = col; this.from = from; } } char[][] maze = { { ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘B‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘ }, { ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘.‘, ‘.‘, ‘.‘, ‘.‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘ }, { ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘.‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘.‘, ‘.‘, ‘#‘ }, { ‘#‘, ‘.‘, ‘.‘, ‘.‘, ‘.‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘.‘, ‘#‘ }, { ‘#‘, ‘.‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘.‘, ‘#‘, ‘#‘, ‘.‘, ‘#‘ }, { ‘#‘, ‘.‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘.‘, ‘#‘, ‘#‘, ‘.‘, ‘#‘ }, { ‘#‘, ‘.‘, ‘#‘, ‘#‘, ‘.‘, ‘.‘, ‘.‘, ‘.‘, ‘.‘, ‘.‘, ‘.‘, ‘#‘ }, { ‘#‘, ‘.‘, ‘#‘, ‘#‘, ‘.‘, ‘#‘, ‘#‘, ‘#‘, ‘.‘, ‘#‘, ‘.‘, ‘#‘ }, { ‘#‘, ‘.‘, ‘.‘, ‘.‘, ‘.‘, ‘#‘, ‘#‘, ‘#‘, ‘.‘, ‘#‘, ‘.‘, ‘#‘ }, { ‘#‘, ‘#‘, ‘.‘, ‘#‘, ‘.‘, ‘#‘, ‘#‘, ‘#‘, ‘.‘, ‘#‘, ‘.‘, ‘A‘ }, { ‘#‘, ‘#‘, ‘.‘, ‘#‘, ‘#‘, ‘#‘, ‘.‘, ‘.‘, ‘.‘, ‘#‘, ‘#‘, ‘#‘ }, { ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘, ‘#‘ } }; // 打印整个迷宫 public void show() { for (int i = 0; i < maze.length; i++) { for (int j = 0; j < maze[i].length; j++) System.out.print(" " + maze[i][j]); System.out.println(); } } public Cell colorCell(Set<Cell> from, Set<Cell> dest) { Iterator<Cell> it = from.iterator(); while (it.hasNext()) { Cell a = it.next(); Cell[] c = new Cell[4]; c[0] = new Cell(a.row - 1, a.col, a); c[1] = new Cell(a.row, a.col - 1, a); c[2] = new Cell(a.row + 1, a.col, a); c[3] = new Cell(a.row, a.col + 1, a); for (int i = 0; i < 4; i++) { if (c[i].row < 0 || c[i].row >= maze.length) continue; if (c[i].col < 0 || c[i].col >= maze[0].length) continue; char x = maze[c[i].row][c[i].col]; if (x == ‘B‘) return a; if (x == ‘.‘) { maze[c[i].row][c[i].col] = ‘?‘; dest.add(c[i]);//代码填空处 } } } return null; } public void resolve() { Set<Cell> set = new HashSet<Cell>(); set.add(new Cell(9, 11, null)); for (;;) { Set<Cell> set1 = new HashSet<Cell>(); Cell a = colorCell(set, set1); if (a != null) { System.out.println("找到解!"); while (a != null) { maze[a.row][a.col] = ‘+‘; a = a.from;// 代码填空处 } break; } if (set1.isEmpty()) { System.out.println("无解!"); break; } set = set1; } } public static void main(String[] args) { Maze m = new Maze(); m.show(); m.resolve(); m.show(); } }
有两个填空的地方,从resolve方法 后面set=set1 可以知道,colorCell(Set<Cell> from, Set<Cell> dest)方法里并没有任何关于dest的赋值,那肯定缺一条关于dest的语句,还有from从头到尾都没用过,所以也是要填的。
整个的思路是,#是墙壁,点是路,调用resolve方法,从A出发,然后以A作为from(from可看成出发的起点),搜索上下左右的四个cell,遇到“.”就把他变为“?”,同时存入Set dest中,这样一直循环,那么所有的路都会成为“?”, 那最终找到B出口后,再一步步回溯,B的from是谁,是B下面那个点,B的下面那个点是哪里来的,是再下面那个,如果此时a为null了,那证明没有路了,无解,如果有,最后还是回到A这个点,回溯的同时,
maze[a.row][a.col] = ‘+‘ 标记了路线符号,这样就找到路线图了。