目录
题目:**16.30(模式识别:连续四个相同的数)
为编程练习题8.19编写一个GUI程序。让用户在6行7列的网格的文本域中输入数字。如果存在一串四个相等的数字,用户单击Solve按钮后,可以高亮现实它们。初始的,文本域中的值随机填充了0到9的数字。
-
习题思路
- 新建一个HBox,放置一个Label,表示当前文本域中是否有连续的四个数。
- 新建一个GridPane,创建一个6行7列的TextField[][]数组,在每一个TextField元素中随机添加一个0~9的数,并设置到GridPane中。
- 新建一个HBox,添加两个Button。
- 新建一个BorderPane,将第一个HBox设置在顶部,将GridPane设置在中心,第二个HBox放在底部。
- 定义一个判断文本域中是否有四个相同的数的方法,可以参考编程练习题8.19的方法。如果找到了四个相同的数,那么将四个输入框位置的坐标添加到另一个数组Int[4][2]中。
- 定义一个设置高亮方法,将Int[4][2]数组中保存的与TextField对应的位置的文本框的边框设置为某一种颜色。
- 定义一个清除高亮方法,使用for循环清除文本边框设置,同时清除Int[4][2]中的数字。
- 还可以为第一个HBox中的Label定义一个设置文本的方法,根据⑤中的方法返回值(或者用一个boolean的值代表是否有连续数),设置Label中的文本。
-
代码示例
编程练习题16_30PatternRecognition.java
package chapter_16;
import java.util.Iterator;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class 编程练习题16_30PatternRecognition extends Application{
private int[][] fourIndex = new int[4][2];
private TextField[][] textList;
private Label prompt;
private boolean bool;
@Override
public void start(Stage primaryStage) throws Exception {
textList = new TextField[6][7];
prompt = new Label();
HBox hBox = new HBox(prompt);
hBox.setAlignment(Pos.CENTER);
GridPane gridPane = new GridPane();
gridPane.setPadding(new Insets(0, 15, 0, 15));
for(int i = 0;i < textList.length;i++) {
for(int j = 0;j < textList[i].length;j++) {
int rand = (int)(Math.random()*10);
textList[i][j] = new TextField(rand+"");
gridPane.add(textList[i][j], i, j);
}
}
Button btSolve = new Button("Solve");
HBox hBox2 = new HBox(btSolve);
hBox2.setAlignment(Pos.CENTER);
BorderPane borderPane = new BorderPane();
borderPane.setTop(hBox);
borderPane.setCenter(gridPane);
borderPane.setBottom(hBox2);
btSolve.setOnAction(e ->{
isConsecutiveFour(textList);
System.out.println(bool);
setLabelText();
});
Scene scene = new Scene(borderPane,200, 200);
primaryStage.setTitle("编程练习题16_30PatternRecognition");
primaryStage.setScene(scene);
primaryStage.show();
}
public void setLabelText() {
if(bool) {
prompt.setText("A consecutive four found");
}else {
prompt.setText("Not a consecutive four found");
clearHighlight();
}
}
public void setHighlight(int[][] fourIndex) {
clearHighlight();
for(int i = 0;i < 4;i++) {
int x;
int y;
x = fourIndex[i][1];
y = fourIndex[i][0];
textList[x][y].setStyle("-fx-border-color:Blue");
System.out.println(x+","+y);
}
}
public void clearHighlight() {
if (textList != null) {
for (int i = 0; i < textList.length; i++) {
for (int j = 0; j < textList[i].length; j++) {
textList[i][j].setStyle("");
}
}
}
for(int i = 0;i < 4;i++) {
fourIndex[i][0] = 0;
fourIndex[i][0] = 0;
}
}
public boolean isConsecutiveFour(TextField[][] values) {
bool = false;
if (values == null || values.length == 0 || values[0].length == 0) {
return false;
}
// 初始化 fourIndex 数组
int[][] fourIndex = new int[4][2];
// 判断行
for (int i = 0; i < values.length; i++) {
int countRow = 0;
int startIndex = -1;
for (int j = 0; j < values[i].length - 1; j++) {
if (j > 0 && values[i][j].getText().equals(values[i][j - 1].getText())) {
countRow++;
if (startIndex == -1) {
startIndex = j - 1; // 记录连续序列的起始索引
}
if (countRow == 3) { // 已经是第四个连续的了
// 填充 fourIndex 数组(这里只填充最后四个索引)
for (int k = 0; k < 4; k++) {
fourIndex[k][0] = startIndex + k;
fourIndex[k][1] = i;
}
setHighlight(fourIndex);
bool = true;
return true;
}
} else {
countRow = 0;
startIndex = -1;
}
}
}
// 判断列
for (int j = 0; j < values[0].length; j++) { // 注意这里应该遍历列数
int countColumn = 0;
int startIndex = -1;
for (int i = 0; i < values.length - 1; i++) { // 注意这里应该是 i < values.length - 1
if (values[i][j].getText().equals(values[i + 1][j].getText())) { // 注意这里使用 i+1 而不是 i-1
countColumn++;
if (startIndex == -1) {
startIndex = i; // 记录连续序列的起始索引
}
if (countColumn == 3) { // 已经是第四个连续的了
// 填充 fourIndex 数组
for (int k = 0; k < 4; k++) {
fourIndex[k][0] = j; // 列索引不变
fourIndex[k][1] = startIndex + k; // 使用行索引的偏移
}
setHighlight(fourIndex);
bool = true;
return true;
}
} else {
countColumn = 0;
startIndex = -1;
}
}
}
// 判断左下到右上的对角线
for (int i = 3; i < values.length; i++) { // 从第四行开始
for (int j = 0; j < values[0].length; j++) { // 确保列索引不会超出范围
int countDiagonal = 1; // 初始化计数器
for (int k = 1; k <= 3; k++) { // 检查接下来的三个元素
int ni = i - k; // 上一个元素的行索引
int nj = j + k; // 下一个元素的列索引
if (ni >= 0 && nj < values[0].length && // 确保索引不会越界
values[i][j].getText().equals(values[ni][nj].getText())) {
countDiagonal++; // 如果元素相同,增加计数器
} else {
countDiagonal = 0; // 重置计数器,因为序列中断了
break; // 跳出内层循环
}
}
// 将判断移到内层循环外部
if (countDiagonal == 4) { // 如果找到了四个相同的元素
// 填充fourIndex
for (int l = 0; l < 4; l++) {
fourIndex[l][1] = i - l; // 行索引递减
fourIndex[l][0] = j + l; // 列索引递增
}
setHighlight(fourIndex);
bool = true;
return true; // 找到后直接返回true
}
}
}
// 检查从左上角到右下角的次对角线
for (int i = 0; i < values.length - 3; i++) { // 注意这里是 <=
for (int j = 0; j < values[0].length - 3; j++) { // 注意这里是 <=
if (values[i][j].getText().equals(values[i + 1][j + 1].getText()) &&
values[i + 1][j + 1].getText().equals(values[i + 2][j + 2].getText()) &&
values[i + 2][j + 2].getText().equals(values[i + 3][j + 3].getText())) {
for (int k = 0; k < 4; k++) {
fourIndex[k][1] = i + k; // 行索引
fourIndex[k][0] = j + k; // 列索引
}
setHighlight(fourIndex);
bool = true;
return true; // 找到后直接返回true
}
}
}
return false;
}
public static void main(String[] args) {
Application.launch(args);
}
}
-
结果展示