问题描述
提示:随机92种,按钮式输出
修改Java黑皮书程序清单22-11的代码,利用按钮遍历92种结果
难点分析:
提示:建议准备好Java基础篇这本书,现学现卖,问题不大。还有其他思路,我是先储存好92种结果之后按钮遍历就好,也可以将事件驱动改一下,每次点击按钮都进行一次计算,前者速度快,消耗少,后者更好操作。
首先是按钮的添加,这个在Java黑皮书(11版)上486页中GridPane示例代码中有讲到,直接套用,先创建一个button对象,之后把这个组件加到面板上就好。
//Create a new button and it's handles
Button nextButton = new Button("Next");
nextButton.setPrefSize(55, 30);
chessBoard.add(nextButton, 2, 8);
Button beforeButton = new Button("Before");
beforeButton.setPrefSize(55, 30);
chessBoard.add(beforeButton, 6, 8);
之后是对原来算法的改进与改造,首先是要理解为什么他只有一种结果,其次是他怎么会有多种结果,对于第一个问题,可能都知道,首先他找值的时候只返回一个结果,结果固定,一次遍历完了就没有第二次遍历了;如果要让他有多个结果并储存好,那么就需要修改代码,这里我们先修改算法:
对于isValid这个方法,书上的方法可以精简,其实用一维数组来做你只需要考虑是否在同一列,和是否在同一斜线上就好了,这里再同一斜线上可以用数学中求斜率的思想Y1 - Y2 / X1 - X2
加上绝对值就好。
public boolean isValid(int n) {
for (int i = 0; i < n; i++) {
if (queens[n] == queens[i] || Math.abs(queens[n] - queens[i]) == Math.abs(n - i)) {
return false;
}
}
return true;
}
对于这里要找到所有的结果,只需要递归就好了,让计算机遍历所有情况然后返回合理的结果:
public void search(int n) {
if (n == 8) {
m++;
record();
return;
}
for (int i = 0; i < 8; i++) {
queens[n] = i;
if (isValid(n)) {
search(n + 1);
}
}
}
最后便是事件的编写,这里建议看一下黑皮书的第15章的事件驱动编程:
nextButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
for (int i = 0; i < SIZE; i++)
labels[i][queenAll[w][i]].setText("");
w++;
if (w > 92){
w = 0;
}
for (int i = 0; i < SIZE; i++)
labels[i][queenAll[w][i]].setText("♛");
System.out.println("第"+w+"种方法");
}
});
beforeButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
for (int i = 0; i < SIZE; i++)
labels[i][queenAll[w][i]].setText("");
w--;
if (w < 0){
w = 92;
}
for (int i = 0; i < SIZE; i++)
labels[i][queenAll[w][i]].setText("♛");
System.out.println("第"+w+"种方法");
}
});
代码:
提示:其中中文可能乱码,改成英文就好
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class EightQueens extends Application {
public static final int SIZE = 8; // The size of the chess board
// queens are placed at (i, queens[i])
// -1 indicates that no queen is currently placed in the ith row
// Initially, place a queen at (0, 0) in the 0th row
private int[] queens = {-1, -1, -1, -1, -1, -1, -1, -1};
private int[][] queenAll = new int[92][8];
private int m = -1;
private int w = 0;
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
search(0); // Search for a solution
// Display chess board
GridPane chessBoard = new GridPane();
chessBoard.setAlignment(Pos.CENTER);
Label[][] labels = new Label[SIZE][SIZE];
for (int i = 0; i < SIZE; i++)
for (int j = 0; j < SIZE; j++) {
chessBoard.add(labels[i][j] = new Label(), j, i);
labels[i][j].setStyle("-fx-border-color: black");
labels[i][j].setPrefSize(55, 55);
}
//Create a new button and it's handles
Button nextButton = new Button("Next");
nextButton.setPrefSize(55, 30);
chessBoard.add(nextButton, 2, 8);
Button beforeButton = new Button("Before");
beforeButton.setPrefSize(55, 30);
chessBoard.add(beforeButton, 6, 8);
nextButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
for (int i = 0; i < SIZE; i++)
labels[i][queenAll[w][i]].setText("");
w++;
if (w > 92){
w = 0;
}
for (int i = 0; i < SIZE; i++)
labels[i][queenAll[w][i]].setText("♛");
System.out.println("第"+w+"种方法");
}
});
beforeButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
for (int i = 0; i < SIZE; i++)
labels[i][queenAll[w][i]].setText("");
w--;
if (w < 0){
w = 92;
}
for (int i = 0; i < SIZE; i++)
labels[i][queenAll[w][i]].setText("♛");
System.out.println("第"+w+"种方法");
}
});
// Display queens
// Image image = new Image("image/queen.jpg");
for (int i = 0; i < SIZE; i++)
labels[i][queenAll[w][i]].setText("♛");
// Create a scene and place it in the stage
Scene scene = new Scene(chessBoard, 55 * SIZE, 55 * SIZE);
primaryStage.setTitle("EightQueens"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
public void search(int n) {
if (n == 8) {
m++;
record();
return;
}
for (int i = 0; i < 8; i++) {
queens[n] = i;
if (isValid(n)) {
search(n + 1);
}
}
}
public boolean isValid(int n) {
for (int i = 0; i < n; i++) {
if (queens[n] == queens[i] || Math.abs(queens[n] - queens[i]) == Math.abs(n - i)) {
return false;
}
}
return true;
}
public void record() {
for (int i = 0; i < queens.length; i++) {
queenAll[m][i] = queens[i];
}
System.out.println();
}
/**
* The main method is only needed for the IDE with limited
* JavaFX support. Not needed for running from the command line.
*/
public static void main(String[] args) {
launch(args);
}
}