JAVA下的第一个程序
来源:互联网 发布:vs2015中开发php 编辑:程序博客网 时间:2024/06/07 08:49
本人是新手。没有系统学过编程的知识。只是对计算机比较感兴趣而已。这是自己写的第一个程序。当然具体方法都是借鉴他人的。但自己也在写的过程中学到了好多平时可能只是听说过,但没真正理解其实质的知识。发现看得懂一段程序是基础,而能自己写才是最重要的。很多时候看懂了,但自己再写就会各种报错。记录一下,当给自己的一种鼓励和鞭策。
这个程序是关于八皇后问题的。按要求用回溯的算法去实现。代码如下。
/** * 回溯法解八皇后问题 * @author Frank */public class Queens {//以(0,0)为原点,皇后的坐标为(Column,Row=Row[Column]),Column为自变量------其实(0,0)应位于左上角public int QueensNum = 8; //皇后数量public int[] Row = new int[QueensNum];//皇后纵坐标,即皇后所在行 public boolean [] RowExist = new boolean [QueensNum];//皇后纵坐标即皇后所在行判断 public boolean [] DiaNEExist = new boolean [2*QueensNum-1];//皇后东北西南方向对角线判断 public boolean [] DiaNWExist = new boolean [2*QueensNum-1];//皇后西北东南方向对角线判断 public int count; //统计每种解法是第几种解 private void initial() { //将3个判断数组初始化,true表示可放皇后,false则相反 for(int i=0; i<=QueensNum-1; i++) { RowExist[i] = true; } for(int i=0; i<=2*QueensNum-2; i++){ DiaNEExist[i]=DiaNWExist[i] = true; } } public boolean Exist(int Column, int Row){ //皇后所在行及两条对角线统一判断 //参数Column是皇后的横坐标,即皇后所在列;Row是纵坐标,皇后所在行 return(RowExist[Row]&& //皇后所在行判断 DiaNEExist[Row-Column+QueensNum-1]&& //对角线方程y=x+b,取值范围-7~7,为防止负数出现,故要加QueensNum-1 DiaNWExist[Row+Column]); //对角线方程y=-x+b } public void print(){ //打印结果 System.out.println("第"+count+"种解法"); for (int i=0; i<=QueensNum-1; i++){ //横坐标,列循环 for (int j=0; j<=QueensNum-1; j++){ //纵坐标,行循环 if(Row[i]==j){ System.out.print("0 "); } else{ System.out.print("+ "); } } System.out.println(); //打印一行后换行 } System.out.println(); //打印一组解法之后的回车 } public void Test (int i){ //i=Column,确定列数,即横坐标,通过递归函数省去了for循环 for(int j=0; j<=QueensNum-1;j++){ //j=Row循环,确定行数,即纵坐标 if(Exist(i, j)){ Row[i]=j; //确定放置皇后的坐标(Column,Row[Column]) RowExist[j]=false; //以下三行将放置后的皇后所在行和对角线 DiaNEExist[j-i+QueensNum-1]=false; //改为不可放置别的皇后的状态。因循环以横坐标 DiaNWExist[j+i]=false; //为自变量,所以可以不考虑所在列的状态改变 if(i==7){ //若已经遍历完所有横坐标,产生了一组放置方法,则打印皇后放置方法 count++; print(); } else{Test (i+1);} //若没有遍历完所有横坐标,则递归,进行下一个皇后的放置 //也是下一步无可放置的皇后的情况下,Test(i+1)出栈后 //Test(i)开始的位置 RowExist[j]=true; //回溯。在下一步无可放置的皇后的情况下,将上一步皇后放置后 DiaNEExist[j-i+QueensNum-1]=true; //产生的别的皇后不可放置的行和对角线取消 DiaNWExist[j+i]=true; //以及在一组解出现之后,再将这组解的最后一个皇后坐标取消 //将其放置后所产生的别的皇后不可放置的的行和对角线取消 } } } public static void main (String args[]){ Queens operate = new Queens(); System.out.println("纪念一下第一个程序"); System.out.println("---------------"); System.out.println(); operate.initial(); operate.Test(0); } }
在写得过程中明白了以下几点:
1、栈的意义:递归会把上一个方法如Test(i)压在栈里,下一个方法Test(i+1)出栈后,会继续执行上一个方法Test(i)。所以递归的入口,也是下一方法出栈之后,上一方法继续执行的起点。正如本程序中的 else{Test (i+1);} 这一行。在Test(i+1)出栈后,会继续执行Test(i)下面的 else{Test (i+1);} 之后的语句,即将上一方法Test(i)下,放置正确的那个皇后形成的判断条件取消,也即回溯。程序就在递归和回溯的作用下不断运行。
2、回溯的那三行语句。它既实现了Test(i+1)失败后,递归回Test(i)之后,将Test(i)中放置正确的皇后形成的判断条件取消的作用,也实现了在找到一种放置8个皇后的方法后,取消第八列上的那个放置正确的皇后形成的判断条件,使程序继续回溯递归,从而遍历所有放置方法的作用。因此,这段语句要放置在打印期盼的if else之后的原因。
3、system.out.println()会自动换行而system.out.print()不会。所以在打印棋盘的+/0号时,要用到后者。
4、自己写能使自己了解一些Java语言语法结构上的东西。如return();&&;||;for(; ; ;)等。
当然也有未解的疑惑和问题:
1、如何在main()方法的最开始就打印出会有多少种解法;
2、想得知程序一共回溯、递归了多少次;
3、想知道其他的非递归解法(据软开的哥们说,那个更简单,因为递归回溯在栈里压的程序太多,费资源)
欢迎各位大大指正。也希望对新手们有所帮助。
- JAVA下的第一个程序
- 第一个java程序(cmd下的调试)
- 第一个linux系统下的java程序
- java的第一个程序
- Java的第一个程序
- JAVA的第一个程序
- Linux下运行第一个JAVA程序
- windows下的第一个makefile程序
- 第一个linux下的C程序
- ubuntu下的第一个c++程序
- windows下的第一个程序
- linux下的第一个c程序
- Jboss下的第一个EJB程序
- Qt下的第一个ACE程序
- Linux下编译的第一个程序
- myeclipse下的webservice第一个程序
- CDH下的第一个MR程序
- windows 下storm的第一个程序
- 图音80系列车载导航/DVD分体机安装DSA
- MVC中使用EF(4):ASP.NET MVC 创建更复杂的数据模型
- 常用的curl发包函数
- 经纬度表示方法及精度
- linux内核--系统调用(四)
- JAVA下的第一个程序
- log4net的配置详解
- 数据库设计三大范式
- 如何配置tomcat
- 七种排序算法
- [OOP]面向对象的一些基础知识
- 网站快照,当天可见效
- 【Leetcode】Validate Binary Search Tree
- 面试常见算法习题1