JAVA经典题目汇总

转 :http://bea.javaeye.com/blog/166344

1 Fibonacci

Fibonacci为1200年代的欧洲数学家,在他的著作中曾经提到:若有一只兔子每个月生一只小兔子,一个月后小兔子也开始生产。起初只有一只兔子,一个月后就有两只兔子,两个月后有三只兔子,三个月后有五只兔子(小兔子投入生产)……
这就是Fibonacci数列,一般习惯称之为费式数列,例如:1,1,2,3,5,8,13,21,34,55,89,……

java代码:

public class Fibonacci { public static void main(String[] args) { int[] fib = new int[20]; fib[0] = 0; fib[1] = 1; for(int i = 2; i < fib.length; i++) fib[i] = fib[i-1] + fib[i-2]; for(int i = 0; i < fib.length; i++) System.out.print(fib[i] + " "); System.out.println(); } }

2 巴斯卡(Pascal)

三角形基本上就是在解nCr ,因为三角形上的每一个数字各对应一个nCr ,其中n为row,而r为colnmu

java代码:

import java.awt.*; import javax.swing.*; public class Pascal extends JFrame { public Pascal() { setBackground(Color.white); setTitle("巴斯卡三角形"); setSize(520, 350); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); show(); } private long combi(int n, int r){ int i; long p = 1; for(i = 1; i <= r; i++) p = p * (n-i+1) / i; return p; } public void paint(Graphics g) { final int N = 12; int n, r, t; for(n = 0; n <= N; n++) { for(r = 0; r <= n; r++) g.drawString(" " + combi(n, r), (N-n)*20 + r * 40, n * 20 + 50); } } public static void main(String args[]) { Pascal frm = new Pascal(); } }

3 ThreeColorFlags


ThreeColorFlags问题最早由E.W.Dijkstra所提出,塔所使用的用语为Dutch Nation Flag(Dijkstra为荷兰人),而多数的作者则使用Three-Color Flag来说明。

假设有一条绳子,上面有红,白,蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,您希望将之分类,并排列蓝,白,红的顺序,要如何移动次数才会最少,注意您只能在绳子上进行这个动作,而且一次只能调换两个旗子。

java代码:

import java.io.*; public class ThreeColorsFlags { private void swap(char[] flags, int x, int y) { char temp; temp = flags[x]; flags[x] = flags[y]; flags[y] = temp; } public String move(char[] flags) { int wFlag = 0; int bFlag = 0; int rFlag = flags.length - 1; while(wFlag <= rFlag) { if(flags[wFlag] == 'W') { wFlag++; } else if(flags[wFlag] == 'B') { swap(flags, bFlag, wFlag); bFlag++; wFlag++; } else { while(wFlag < rFlag && flags[rFlag] == 'R') rFlag--; swap(flags, rFlag, wFlag); rFlag--; } } return new String(flags); } public static void main(String[] args) throws IOException { BufferedReader buf; buf = new BufferedReader( new InputStreamReader(System.in)); System.out.print("输入三色旗顺序(ex. RWBBWRWR):"); String flags = buf.readLine(); ThreeColorsFlags threeColorsFlag = new ThreeColorsFlags(); flags = threeColorsFlag.move( flags.toUpperCase().toCharArray()); System.out.println("移动顺序后:" + flags); } }

4 Mouse


Mouse走迷宫是循环求解的基本类型,我们在二维数组中用2来表示迷宫的墙壁,使用1来表示老鼠的行走路径,并用程序求出从入口到出口的距离。

java代码:

public class Mouse { private int startI, startJ; // 入口 private int endI, endJ; // 出口 private boolean success = false; public static void main(String[] args) { int[][] maze = {{2, 2, 2, 2, 2, 2, 2}, {2, 0, 0, 0, 0, 0, 2}, {2, 0, 2, 0, 2, 0, 2}, {2, 0, 0, 2, 0, 2, 2}, {2, 2, 0, 2, 0, 2, 2}, {2, 0, 0, 0, 0, 0, 2}, {2, 2, 2, 2, 2, 2, 2}}; System.out.println("显示迷宫:"); for(int i = 0; i < maze.length; i++) { for(int j = 0; j < maze[0].length; j++) if(maze[j] == 2) System.out.print("█"); else System.out.print(" "); System.out.println(); } Mouse mouse = new Mouse(); mouse.setStart(1, 1); mouse.setEnd(5, 5); if(!mouse.go(maze)) { System.out.println("/n没有找到出口!"); } else { System.out.println("/n找到出口!"); for(int i = 0; i < maze.length; i++) { for(int j = 0; j < maze[0].length; j++) { if(maze[j] == 2) System.out.print("█"); else if(maze[j] == 1) System.out.print("◇"); else System.out.print(" "); } System.out.println(); } } } public void setStart(int i, int j) { this.startI = i; this.startJ = j; } public void setEnd(int i, int j) { this.endI = i; this.endJ = j; } public boolean go(int[][] maze) { return visit(maze, startI, startJ); } private boolean visit(int[][] maze, int i, int j) { maze[j] = 1; if(i == endI && j == endJ) success = true; if(!success && maze[j+1] == 0) visit(maze, i, j+1); if(!success && maze[i+1][j] == 0) visit(maze, i+1, j); if(!success && maze[j-1] == 0) visit(maze, i, j-1); if(!success && maze[i-1][j] == 0) visit(maze, i-1, j); if(!success) maze[j] = 0; return success; } }

5 Knight tour


骑士游戏,在十八世纪倍受数学家与拼图迷的注意,骑士的走法为西洋棋的走发,骑士可以由任何一个位置出发,它要如何走完所有的位置。

java代码:

public class Knight { public boolean travel(int startX, int startY, int[][] board) { // 对应骑士可以走的八个方向 int[] ktmove1 = {-2, -1, 1, 2, 2, 1, -1, -2}; int[] ktmove2 = {1, 2, 2, 1, -1, -2, -2, -1}; // 下一个出路的位置 int[] nexti = new int[board.length]; int[] nextj = new int[board.length]; // 记录出路的个数 int[] exists = new int[board.length]; int x = startX; int y = startY; board[x][y] = 1; for(int m = 2; m <= Math.pow(board.length, 2); m++) { for(int k = 0; k < board.length; k++) { exists[k] = 0; } int count = 0; // 试探八个方向 for(int k = 0; k < board.length; k++) { int tmpi = x + ktmove1[k]; int tmpj = y + ktmove2[k]; // 如果是边界,不可以走 if(tmpi < 0 || tmpj < 0 || tmpi > 7 || tmpj > 7) { continue; } // 如果这个方向可以走,记录下来 if(board[tmpi][tmpj] == 0) { nexti[count] = tmpi; nextj[count] = tmpj; // 可走的方向加一个 count++; } } int min = -1; if(count == 0) { return false; } else if(count == 1) { min = 0; } else { // 找出下个位置的出路数 for(int l = 0; l < count; l++) { for(int k = 0; k < board.length; k++) { int tmpi = nexti[l] + ktmove1[k]; int tmpj = nextj[l] + ktmove2[k]; if(tmpi < 0 || tmpj < 0 || tmpi > 7 || tmpj > 7) { continue; } if(board[tmpi][tmpj] == 0) exists[l]++; } } int tmp = exists[0]; min = 0; // 从可走的方向寻找最少出路的方向 for(int l = 1; l < count; l++) { if(exists[l] < tmp) { tmp = exists[l]; min = l; } } } // 走最少出路的方向 x = nexti[min]; y = nextj[min]; board[x][y] = m; } return true; } public static void main(String[] args) { int[][] board = new int[8][8]; Knight knight = new Knight(); if(knight.travel( Integer.parseInt(args[0]), Integer.parseInt(args[1]), board)) { System.out.println("走棋完成!"); } else { System.out.println("走棋失败!"); } for(int i = 0; i < board.length; i++) { for(int j = 0; j < board[0].length; j++) { if(board[i][j] < 10) { System.out.print(" " + board[i][j]); } else { System.out.print(board[i][j]); } System.out.print(" "); } System.out.println(); } } }

6 Queen


西洋棋中的皇后可以直线前进,吃掉遇到的所有棋子,如果棋盘上有八个皇后,则这八个皇后如何相安无事的放置在棋盘上?

java代码:

public class Queen { // 同位置是否有皇后,1表示有 private int[] column; // 右上至左下是否有皇后 private int[] rup; // 左上至右下是否有皇后 private int[] lup; // 解答 private int[] queen; // 解答编号 private int num; public Queen() { column = new int[8+1]; rup = new int[2*8+1]; lup = new int[2*8+1]; for(int i = 1; i <= 8; i++) column[i] = 1; for(int i = 1; i <= 2*8; i++) rup[i] = lup[i] = 1; queen = new int[8+1]; } public void backtrack(int i) { if(i ><IMG src="/images/smiles/icon_cool.gif" mce_src="images/smiles/icon_cool.gif">{ showAnswer(); } else { for(int j = 1; j <= 8; j++) { if(column[j] == 1 && rup[i+j] == 1 && lup[i-j+8] == 1) { queen[i] = j; // 设定为占用 column[j] = rup[i+j] = lup[i-j+8] = 0; backtrack(i+1); column[j] = rup[i+j] = lup[i-j+8] = 1; } } } } protected void showAnswer() { num++; System.out.println("/n解答 " + num); for(int y = 1; y <= 8; y++) { for(int x = 1; x <= 8; x++) { if(queen[y] == x) { System.out.print(" Q"); } else { System.out.print(" ."); } } System.out.println(); } } public static void main(String[] args) { Queen queen = new Queen(); queen.backtrack(1); } }


7 Coins


现在有八枚银币abcdefg,已知其中一枚是假币,其重量不同于真币,但不知道是轻还是重,如何用天平以最小的比较次数决定出那个是假币,并得知假币是比真币轻还是重。

java代码:

public class Coins { private int[] coins; public Coins() { coins = new int[8]; for(int i = 0; i < 8; i++) coins[i] = 10; } public void setFake(int weight) { coins[(int) (Math.random() * 7)] = weight; } public void fake() { if(coins[0]+coins[1]+coins[2] == coins[3]+coins[4]+coins[5]) { if(coins[6] > coins[7]) compare(6, 7, 0); else compare(7, 6, 0); } else if(coins[0]+coins[1]+coins[2] > coins[3]+coins[4]+coins[5]) { if(coins[0]+coins[3] == coins[1]+coins[4]) compare(2, 5, 0); else if(coins[0]+coins[3] > coins[1]+coins[4]) compare(0, 4, 1); if(coins[0]+coins[3] < coins[1]+coins[4]) compare(1, 3, 0); } else if(coins[0]+coins[1]+coins[2] < coins[3]+coins[4]+coins[5]) { if(coins[0]+coins[3] == coins[1]+coins[4]) compare(5, 2, 0); else if(coins[0]+coins[3] > coins[1]+coins[4]) compare(3, 1, 0); if(coins[0]+coins[3] < coins[1]+coins[4]) compare(4, 0, 1); } } protected void compare(int i, int j, int k) { if(coins[i] > coins[k]) System.out.print("/n假币 " + (i+1) + " 较重"); else System.out.print("/n假币 " + (j+1) + " 较轻"); } public static void main(String[] args) { if(args.length == 0) { System.out.println("输入假币重量(比10大或小)"); System.out.println("ex. java Coins 5"); return; } Coins eightCoins = new Coins(); eightCoins.setFake(Integer.parseInt(args[0])); eightCoins.fake(); } }

8 Life game


生命游戏,为1970年英国数学家J.H.Conway所提出,某一细胞的邻居包括上,下,左,右,左上,左下,右上与右下相邻的细胞,游戏规则如下:

1,孤单死亡:如果细胞的邻居小于一个,则该细胞在下一个状态死亡。

2,拥挤死亡:如果细胞的邻居在四个以上,则该细胞在下一个状态死亡。

3,稳定:如果细胞的邻居为两个或三个,则该细胞在下一个状态稳定。

4,复活:如果某位置原无细胞存活,而该位置的邻居为三个,则该位置将复活一个细胞。

java代码:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class LifeGame { private boolean[][] map; private boolean[][] newmap; public LifeGame(int maxRow, int maxColumn) { map = new boolean[maxRow][maxColumn]; newmap = new boolean[maxRow][maxColumn]; } public void setCell(int x, int y) { map[x][y] = true; } public void next() { for(int row = 0; row < map.length; row++) { for(int col = 0; col < map[0].length; col++) { switch (neighbors(row, col)) { case 0: case 1: case 4: case 5: case 6: case 7: case 8: newmap[row][col] = false; break; case 2: newmap[row][col] = map[row][col]; break; case 3: newmap[row][col] = true; break; } } } copyMap(); } public void outputMap() throws IOException { System.out.println("/n/nGame of life cell status"); for(int row = 0; row < map.length; row++) { System.out.print("/n "); for(int col = 0; col < map[0].length; col++) if(map[row][col] == true) System.out.print('#'); else System.out.print('-'); } } private void copyMap() { for(int row = 0; row < map.length; row++) for(int col = 0; col < map[0].length; col++) map[row][col] = newmap[row][col]; } private int neighbors(int row, int col) { int count = 0; for(int r = row-1; r <= row+1; r++) for(int c = col-1; c <= col+1; c++) { if(r < 0 || r >= map.length || c < 0 || c >= map[0].length) continue; if(map[r][c] == true) count++; } if(map[row][col] == true) count--; return count; } public static void main(String[] args) throws NumberFormatException, IOException { BufferedReader bufReader = new BufferedReader( new InputStreamReader(System.in)); LifeGame game = new LifeGame(10, 25); System.out.println("Game of life Program"); System.out.println( "Enter x, y where x, y is living cell"); System.out.println("0 <= x < 10, 0 <= y < 25"); System.out.println("Terminate with x, y = -1, -1"); while(true) { String[] strs = bufReader.readLine().split(" "); int row = Integer.parseInt(strs[0]); int col = Integer.parseInt(strs[1]); if(0 <= row && row < 10 && 0 <= col && row < 25) game.setCell(row, col); else if(row == -1 || col == -1) { break; } else { System.out.print( "(x, y) exceeds map ranage!"); } } while(true) { game.outputMap(); game.next(); System.out.print( "/nContinue next Generation ? "); String ans = bufReader.readLine().toUpperCase(); if(!ans.equals("Y")) break; } } }

9 String Match


现在的一些高级程序语言对于字符串的处理支持越来越大,不过字符串搜寻本身仍是值得探讨的课题,在这里以Boyer Moore法来说明如何进行字符串说明,这个方法速度快且容易理解。

java代码:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class StringMatch { private int[] skip; private int p; private String str; private String key; public StringMatch(String key) { skip = new int[256]; this.key = key; for(int k = 0; k <= 255; k++) skip[k] = key.length(); for(int k = 0; k < key.length() - 1; k++) skip[key.charAt(k)] = key.length() - k - 1; } public void search(String str) { this.str = str; p = search(key.length()-1, str, key); } private int search(int p, String input, String key) { while(p < input.length()) { String tmp = input.substring( p-key.length()+1, p+1); if(tmp.equals(key)) // 比较两个字符串是否相同 return p-key.length()+1; p += skip[input.charAt(p)]; } return -1; } public boolean hasNext() { return (p != -1); } public String next() { String tmp = str.substring(p); p = search(p+key.length()+1, str, key); return tmp; } public static void main(String[] args) throws IOException { BufferedReader bufReader = new BufferedReader( new InputStreamReader(System.in)); System.out.print("请输入字符串:"); String str = bufReader.readLine(); System.out.print("请输入搜寻关键字:"); String key = bufReader.readLine(); StringMatch strMatch = new StringMatch(key); strMatch.search(str); while(strMatch.hasNext()) { System.out.println(strMatch.next()); } } }

10 Kanpsack Problem


假设一个背包的负重最大可达8公斤,而希望在背包内放置负重范围你价值最高的物品。

java代码:

class Fruit { private String name; private int size; private int price; public Fruit(String name, int size, int price) { this.name = name; this.size = size; this.price = price; } public String getName() { return name; } public int getPrice() { return price; } public int getSize() { return size; } } public class Knapsack { public static void main(String[] args) { final int MAX = 8; final int MIN = 1; int[] item = new int[MAX+1]; int[] value = new int[MAX+1]; Fruit fruits[] = { new Fruit("李子", 4, 4500), new Fruit("苹果", 5, 5700), new Fruit("桔子", 2, 2250), new Fruit("草莓", 1, 1100), new Fruit("甜瓜", 6, 6700)}; for(int i = 0; i < fruits.length; i++) { for(int s = fruits[i].getSize(); s <= MAX; s++) { int p = s - fruits[i].getSize(); int newvalue = value[p] + fruits[i].getPrice(); if(newvalue > value[s]) {// 找到阶段最佳解 value[s] = newvalue; item[s] = i; } } } System.out.println("物品/t价格"); for(int i = MAX; i >= MIN; i = i - fruits[item[i]].getSize()) { System.out.println(fruits[item[i]].getName()+ "/t" + fruits[item[i]].getPrice()); } System.out.println("合计/t" + value[MAX]); } }

11 Towers of Hanoi

河內之塔(Towers of Hanoi)是法国人M.Claus(Lucas)於1883年从泰国带至法国的,河內为越战时北越的首都,即现在的胡志明市;1883年法国数学家 Edouard Lucas曾提及這个故事,据说创世紀时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),並命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将损毁,而也就是世界末日來临之时。

java代码:

import java.io.*; public class Hanoi { public static void main(String args[]) throws IOException { int n; BufferedReader buf; buf = new BufferedReader(new InputStreamReader(System.in)); System.out.print("请输入盘子个数"); n = Integer.parseInt(buf.readLine()); Hanoi hanoi = new Hanoi(); hanoi.move(n, 'A', 'B', 'C'); } public void move(int n, char a, char b, char c) { if(n == 1) System.out.println("盘 " + n + " 由 " + a + " 移至 " + c); else { move(n - 1, a, c, b); System.out.println("盘 " + n + " 由 " + a + " 移至 " + c); move(n - 1, b, a, c); } } }

12 Hanoi2Colors


Hanoi2Colors是由河内塔演变而来的一种算法。

java代码:

public class Hanoi2Colors { public static void help() { System.out.println( "Usage: java Hanoi2Colors number_of_disks"); System.out.println( "/t number_of_disks: must be a even number."); System.exit(0); } public static void main(String[] args) { int disks = 0; try { disks = Integer.parseInt(args[0]); } catch (Exception e) { help(); } if ((disks <= 0) || (disks % 2 != 0)) { help(); } hanoi2colors(disks); } public static void hanoi(int disks, char source, char temp, char target) { if (disks == 1) { System.out.println("move disk from " + source + " to " + target); System.out.println("move disk from " + source + " to " + target); } else { hanoi(disks-1, source, target, temp); hanoi(1, source, temp, target); hanoi(disks-1, temp, source, target); } } public static void hanoi2colors(int disks) { char source = 'A'; char temp = 'B'; char target = 'C'; for (int i = disks / 2; i > 1; i--) { hanoi(i-1, source, temp, target); System.out.println("move disk from " + source + " to " + temp); System.out.println("move disk from " + source + " to " + temp); hanoi(i-1, target, temp, source); System.out.println("move disk from " + temp + " to " + target); } System.out.println("move disk from " + source + " to " + temp); System.out.println("move disk from " + source + " to " + target); } }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值