Java算法之经典题目篇.docx
《Java算法之经典题目篇.docx》由会员分享,可在线阅读,更多相关《Java算法之经典题目篇.docx(27页珍藏版)》请在冰豆网上搜索。
Java算法之经典题目篇
Java算法之经典题目篇
费式数列(Fibonacci)问题说明:
Fibonacci为1200年代的欧洲数学家,在他的著作中曾经提到:
若有一只兔子每个月生一只小兔子,一个月后小兔子也开始生产。
起初只有一只兔子,一个月后就有两只兔子,两个月后有三只兔子,三个月后有五只兔子(小兔子投入生产)……
这就是Fibonacci数列,一般习惯称之为费式数列,例如:
1,1,2,3,5,8,13,21,34,55,89,……
算法代码(Java):
publicclassFibonacci
{
publicstaticvoidmain(String[]args)
{
int[]fib=newint[20];
fib[0]=0;
fib[1]=1;
for(inti=2;i fib[i]=fib[i-1]+fib[i-2];
for(inti=0;i System.out.print(fib[i]+"");
System.out.println();
}
}
巴斯卡三角形(Pascal)
问题说明:
巴斯卡(Pascal)三角形基本上就是在解C
算法代码(Java):
importjava.awt.*;
importjavax.swing.*;
publicclassPascalextendsJFrame{
publicPascal(){
setBackground(Color.white);
setTitle("巴斯卡三角形");
setSize(520,350);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
show();
}
privatelongcombi(intn,intr){
inti;
longp=1;
for(i=1;i<=r;i++)
p=p*(n-i+1)/i;
returnp;
}
publicvoidpaint(Graphicsg){
finalintN=12;
intn,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);
}
}
publicstaticvoidmain(Stringargs[]){
Pascalfrm=newPascal();
}
}
三色旗(ThreeColorFlags)
问题说明:
三色旗的问题最早由E.W.Dijkstra所提出,塔所使用的用语为DutchNationFlag(Dijkstra为荷兰人),而多数的作者则使用Three-ColorFlag来说明。
假设有一条绳子,上面有红,白,蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,您希望将之分类,并排列蓝,白,红的顺序,要如何移动次数才会最少,注意您只能在绳子上进行这个动作,而且一次只能调换两个旗子。
算法代码(Java):
importjava.io.*;
publicclassThreeColorsFlags{
privatevoidswap(char[]flags,intx,inty){
chartemp;
temp=flags[x];
flags[x]=flags[y];
flags[y]=temp;
}
publicStringmove(char[]flags){
intwFlag=0;
intbFlag=0;
intrFlag=flags.length-1;
while(wFlag<=rFlag){
if(flags[wFlag]=='W'){
wFlag++;
}
elseif(flags[wFlag]=='B'){
swap(flags,bFlag,wFlag);
bFlag++;
wFlag++;
}
else{
while(wFlag rFlag--;
swap(flags,rFlag,wFlag);
rFlag--;
}
}
returnnewString(flags);
}
publicstaticvoidmain(String[]args)
throwsIOException{
BufferedReaderbuf;
buf=newBufferedReader(
newInputStreamReader(System.in));
System.out.print("输入三色旗顺序(ex.RWBBWRWR):
");
Stringflags=buf.readLine();
ThreeColorsFlagsthreeColorsFlag=newThreeColorsFlags();
flags=threeColorsFlag.move(
flags.toUpperCase().toCharArray());
System.out.println("移动顺序后:
"+flags);
}
}
老鼠走迷宫(Mouse)
问题说明:
老鼠走迷宫是循环求解的基本类型,我们在二维数组中用2来表示迷宫的墙壁,使用1来表示老鼠的行走路径,并用程序求出从入口到出口的距离。
算法代码(Java):
publicclassMouse{
privateintstartI,startJ; //入口
privateintendI,endJ; //出口
privatebooleansuccess=false;
publicstaticvoidmain(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(inti=0;i for(intj=0;j if(maze[j]==2)
System.out.print("█");
else
System.out.print(" ");
System.out.println();
}
Mousemouse=newMouse();
mouse.setStart(1,1);
mouse.setEnd(5,5);
if(!
mouse.go(maze)){
System.out.println("\n没有找到出口!
");
}
else{
System.out.println("\n找到出口!
");
for(inti=0;i for(intj=0;j if(maze[j]==2)
System.out.print("█");
elseif(maze[j]==1)
System.out.print("◇");
else
System.out.print(" ");
}
System.out.println();
}
}
}
publicvoidsetStart(inti,intj){
this.startI=i;
this.startJ=j;
}
publicvoidsetEnd(inti,intj){
this.endI=i;
this.endJ=j;
}
publicbooleango(int[][]maze){
returnvisit(maze,startI,startJ);
}
privatebooleanvisit(int[][]maze,inti,intj){
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;
returnsuccess;
}
}
由于迷宫的设计,老鼠从迷宫的入口到出口的路径可能不只一条,下面我们显示所有路径。
publicclassMouse{
privateintstartI,startJ; //入口
privateintendI,endJ; //出口
publicstaticvoidmain(String[]args){
intmaze[][]={{2,2,2,2,2,2,2,2,2},
{2,0,0,0,0,0,0,0,2},
{2,0,2,2,0,2,2,0,2},
{2,0,2,0,0,2,0,0,2},
{2,0,2,0,2,0,2,0,2},
{2,0,0,0,0,0,2,0,2},
{2,2,0,2,2,0,2,2,2},
{2,0,0,0,0,0,0,0,2},
{2,2,2,2,2,2,2,2,2}};
System.out.println("显示迷宫:
");
for(inti=0;i for(intj=0;j if(maze[i][j]==2)
System.out.print("█");
else
System.out.print(" ");
System.out.println();
}
Mousemouse=newMouse();
mouse.setStart(1,1);
mouse.setEnd(7,7);
mouse.go(maze);
}
publicvoidsetStart(inti,intj){
this.startI=i;
this.startJ=j;
}
publicvoidsetEnd(inti,intj){
this.endI=i;
this.endJ=j;
}
publicvoidgo(int[][]maze){
visit(maze,startI,startJ);
}
privatevoidvisit(int[][]maze,inti,intj){
maze[i][j]=1;
if(i==endI&&j==endJ){
System.out.println("\n找到出口!
");
for(intm=0;m for(intn=0;n if(maze[m][n]==2)
System.out.print("█");
elseif(maze[m][n]==1)
System.out.print("◇");
else
System.out.print(" ");
}
System.out.println();
}
}
if(maze[i][j+1]==0)
visit(maze,i,j+1);
if(maze[i+1][j]==0)
visit(maze,i+1,j);
if(maze[i][j-1]==0)
visit(maze,i,j-1);
if(maze[i-1][j]==0)
visit(maze,i-1,j);
maze[i][j]=0;
}
}
骑士走棋盘(Knighttour)
问题说明:
骑士游戏,在十八世纪倍受数学家与拼图迷的注意,骑士的走法为西洋棋的走发,骑士可以由任何一个位置出发,它要如何走完所有的位置。
算法代码(Java):
publicclassKnight{
publicbooleantravel(intstartX,
intstartY,int[][]board){
//对应骑士可以走的八个方向
int[]ktmove1={-2,-1,1,2,2,1,-1,-2};
int[]ktmove2={1,2,2,1,-1,-2,-2,-1};
//下一个出路的位置 int[]nexti=newint[board.length];
int[]nextj=newint[board.length];
//记录出路的个数
int[]exists=newint[board.length];
intx=startX;
inty=startY;
board[x][y]=1;
for(intm=2;m<=Math.pow(board.length,2);m++){
for(intk=0;k exists[k]=0;
}
intcount=0;
//试探八个方向
for(intk=0;k inttmpi=x+ktmove1[k];
inttmpj=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++;
}
}
intmin=-1;
if(count==0){
returnfalse;
}
elseif(count==1){
min=0;
}
else{