c语言多文件递归设计数独,用于解决数独的递归方法

我目前正在学习我在java中的第二门编程课程,并且需要完成一门任务才能通过课程。基本上它是关于编写一个递归解决数独与回溯的程序。这是我想出的算法。我用一个9x9数组来表示开始时填充零的网格。 checkFill检查是否可以将数字(var)插入位置[i] [j]。问题是它只能部分解决数独它总是返回false(没有解决方案),一些单元格仍然包含零。我在这里做错了什么?用于解决数独的递归方法

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.*;

public class Sudoku {

private int[][] sudoku;

private JFrame frame;

private JFormattedTextField[][] sudokuSquares;

private JButton solve, clear;

public Sudoku() {

sudoku = new int[9][9];

frame = new JFrame("Sudoku Solver");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel northPanel = new JPanel();

northPanel.setLayout(new GridLayout(9, 9));

northPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

sudokuSquares = new JFormattedTextField[9][9];

Font font1 = new Font("SansSerif", Font.BOLD, 20);

for(int i = 0; i < 9; i++) {

for(int j = 0; j < 9; j++) {

sudokuSquares[i][j] = new JFormattedTextField();

sudokuSquares[i][j].setHorizontalAlignment(JTextField.CENTER);

sudokuSquares[i][j].setFont(font1);

sudokuSquares[i][j].setBorder(BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED));

northPanel.add(sudokuSquares[i][j]);

}

}

setColor();

frame.add(northPanel, BorderLayout.NORTH);

JPanel southPanel = new JPanel();

solve = new JButton("Solve");

solve.addActionListener(new SolveButtonListener());

clear = new JButton("Clear");

clear.addActionListener(new ClearButtonListener());

southPanel.add(clear);

southPanel.add(solve);

frame.add(southPanel, BorderLayout.SOUTH);

frame.setResizable(false);

frame.setSize(280, 330);

frame.setVisible(true);

}

private void solveSudoku() {

boolean hasSolution = solve(0, 0);

if(hasSolution) {

JOptionPane.showMessageDialog(frame, "Sudoku has been successfully solved");

} else {

JOptionPane.showMessageDialog(frame, "Sudoku has no solution");

}

}

private class SolveButtonListener implements ActionListener {

@Override

/**

* Checks input for errors and outputs the sudoku matrix after it's been solved.

*/

public void actionPerformed(ActionEvent e) {

String s;

setColor();

for(int i = 0; i < 9; i++) {

for(int j = 0; j < 9; j++) {

s = sudokuSquares[i][j].getText();

if(s.isEmpty()) {

s = "0";

} else if(s.length() > 1 || !Character.isDigit(s.charAt(0)) || s.charAt(0) == '0') {

sudokuSquares[i][j].setBackground(Color.RED);

JOptionPane.showMessageDialog(frame, "Invalid entry! Please enter a number between 1-9");

return;

}

sudoku[i][j] = Integer.parseInt(s);

}

}

solveSudoku();

for(int i = 0; i < 9; i++) {

for(int j = 0; j < 9; j++) {

sudokuSquares[i][j].setText(String.valueOf(sudoku[i][j]));

}

}

}

}

private class ClearButtonListener implements ActionListener {

@Override

public void actionPerformed(ActionEvent e) {

for(int i = 0; i < 9; i++) {

for(int j = 0; j < 9; j++) {

sudokuSquares[i][j].setText("");

}

}

setColor();

}

}

/**

* Sets the background color of sudoku cells

*/

private void setColor() {

for(int i = 0; i < 9; i++) {

for(int j = 0; j < 9; j++) {

if((i/3 < 1 || i/3 >= 2) && (j/3 < 1 || j/3 >= 2) ||

(i/3 >= 1 && i/3 < 2) && (j/3 >= 1 && j/3 < 2)) {

sudokuSquares[i][j].setBackground(new Color(220, 220, 220));

} else {

sudokuSquares[i][j].setBackground(Color.WHITE);

}

}

}

}

/**

* Solves the sudoku through recursive technique

* @param i row

* @param j column

* @return returns true if the sudoku has a solution, returns false otherwise

*/

private boolean solve(int i, int j) {

if(i > 8) {

return true;

}

if(sudoku[i][j] == 0) {

for(int var = 1; var < 10; var++) {

if(checkFill(i, j, var)) {

sudoku[i][j] = var;

if(j >= 8) {

solve(i + 1, 0);

} else {

solve(i, j+1);

}

}

}

} else {

if(j >= 8) {

solve(i + 1, 0);

} else {

solve(i, j+1);

}

}

return false;

}

/**

* Checks if var could be inserted at position [i][j]

* @param i row

* @param j column

* @param var number to be checked for possible insertion

* @return

*/

private boolean checkFill(int i, int j, int var) {

for(int a = 0; a < 9; a++) {

if(sudoku[a][j] == var) {

return false;

}

}

for(int a = 0; a < 9; a++) {

if(sudoku[i][a] == var) {

return false;

}

}

int tempI = (i/3) * 3;

int tempJ = (j/3) * 3;

for(int a = 0; a < 3; a++) {

for(int b = 0; b < 3; b++) {

if(sudoku[tempI + a][tempJ + b] == var)

return false;

}

}

return true;

}

}

那么有人有什么想法?

+1

你试过调试过吗? –

2013-03-11 06:03:41

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值