目前能够解出简单的数独,用于交流使用,欢迎大家吐槽,现在贴出代码。
程序入口:
package com.mt.snippet;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
/**
* 没事闲着蛋疼写九宫格解法,你说蛋疼不。
* 还不能解全部的,复杂的就解不出来了
* @author Administrator
*
*/
public class App {
public static void main(String[] args) throws Exception{
/*
5-1-9-428
4-2--31--
-9---16-3
----1-98-
-2-5-7-6-
-85-6----
9-61---3-
--36--7-9
247-3-5-6
文件内容请遵循上面的格式,-表示待计算的内容
*/
File file = new File("D:\\1.txt");
Table table = initData(file);
table.print();
System.out.println("-----------------------------");
Snippet.getInstance().imitate(table);
}
public static Table initData(File file) throws Exception{
Table table = new Table();
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
int i = 0;
Integer num = null;
while(reader.ready()){
String line = reader.readLine();
char[] numbers = line.toCharArray();
for (int j = 0; j < numbers.length; j++) {
String str = Character.toString(numbers[j]);
num = str.equals("-") ? null : Integer.parseInt(str);
table.initData(i, j, num);
}
i++;
}
reader.close();
reader = null;
return table;
}
}
上面入口需要按照我注释部分进行贴出九宫格的部分数据,以便于程序计算,这里我在D盘里面建了一个文本文档。
package com.mt.snippet;
import java.util.ArrayList;
import java.util.List;
public class Cell {
//当前格子内容
private Integer num;
//预选内容
private List<Integer> preelectionList;
//备份预选内容
private List<Integer> backPreelectionList;
private int index = 0;
private Point point;
public Cell(Integer num){
this.num = num;
preelectionList = new ArrayList<Integer>();
}
/**
* 添加预选内容
* @param value
*/
public void addPreelectionNum(Integer value){
preelectionList.add(value);
}
public List<Integer> getPreelectionList() {
return preelectionList;
}
public String toPreelection(){
StringBuffer sb = new StringBuffer();
sb.append("[");
for (int i = 0; i < preelectionList.size(); i++) {
sb.append(preelectionList.get(i)).append(",");
}
if(sb.length() > 1){
sb.delete(sb.length()-1, sb.length());
}
sb.append("]");
return sb.toString();
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public List<Integer> getBackPreelectionList() {
return backPreelectionList;
}
public void setBackPreelectionList(List<Integer> backPreelectionList) {
this.backPreelectionList = backPreelectionList;
}
}
这里我将每个格子做为一个实体进行存储,用于求解。
package com.mt.snippet;
public interface Constant {
/*
LEN{
public int getLen(){
return 9;
}
};
//九宫格长度
public abstract int getLen();
*/
//九宫格长度
public static final Integer LEN = 9;
//分割线
public static final String SPLICE = "\\|";
//九宫格小格子行范围
public static final String ROW_START_RANGE = "ROW_START_RANGE";
public static final String ROW_END_RANGE = "ROW_END_RANGE";
//九宫格小格子列范围
public static final String CELL_START_RANGE = "CELL_START_RANGE";
public static final String CELL_END_RANGE = "CELL_END_RANGE";
}
package com.mt.snippet;
public class Control {
private boolean isOver;
private int overCount;
public boolean isOver() {
return isOver;
}
public void setOver(boolean isOver) {
this.isOver = isOver;
}
public int getOverCount() {
return overCount;
}
public void setOverCount(int overCount) {
this.overCount = overCount;
}
}
package com.mt.snippet;
public class Point {
public Point(Integer rowIndex, Integer cellIndex) {
super();
this.rowIndex = rowIndex;
this.cellIndex = cellIndex;
}
private Integer rowIndex;
private Integer cellIndex;
public Integer getRowIndex() {
return rowIndex;
}
public void setRowIndex(Integer rowIndex) {
this.rowIndex = rowIndex;
}
public Integer getCellIndex() {
return cellIndex;
}
public void setCellIndex(Integer cellIndex) {
this.cellIndex = cellIndex;
}
}
格子的位置
package com.mt.snippet;
import java.util.ArrayList;
import java.util.List;
public class Row {
private List<Cell> cells;
/**
* 初始化添加N个单元格
*/
public Row(){
cells = new ArrayList<Cell>();
for (int i = 0; i < Constant.LEN; i++) {
cells.add(new Cell(null));
}
}
public Cell get(int index) {
return cells.get(index);
}
/**
* 设置当前行为单元格集合
* @param cells
*/
public void setCellRange(List<Cell> cells) {
this.cells = cells;
}
/**
* 设置指定单元格内容
* @param cells
*/
public void setCell(int index,Cell cell) {
this.cells.remove(index);
this.cells.set(index, cell);
}
public int size(){
return this.cells.size();
}
}
行表示
package com.mt.snippet;
import java.util.List;
import java.util.Map;
public class Snippet {
private static Snippet instance = new Snippet();
private Snippet(){
}
public static Snippet getInstance(){
return instance;
}
/**
* 模拟数据
* @param table
*/
public void imitate(Table table){
int maxLength = 0;
boolean loop = false;
do{
try{
maxLength = calc(table);
table.printPreelection(maxLength);
Control control = handlePreelection(table);
loop = control.isOver();
if(control.isOver() == false && control.getOverCount() == 0){
//假设
//Calculate.getInstance().calculate(table);
System.out.println("算不出...");
System.exit(-1);
}
Thread.sleep(50);
System.out.println("---------------------------");
}catch(Exception ex){
ex.printStackTrace();
}
}while(!loop);
}
/**
* 处理已经计算出来的结果
* @param table
* @return
*/
private Control handlePreelection(Table table){
List<Row> rows = table.getItems();
boolean isOver = true;
int overCount = 0;
Control control = new Control();
for (int i = 0; i < rows.size(); i++) {
Row row = rows.get(i);
for (int j = 0; j < row.size(); j++) {
Cell cell = row.get(j);
if(cell.getPreelectionList().size() == 1){
cell.setNum(cell.getPreelectionList().get(0));
overCount ++;
}
if(cell.getNum() == null){
isOver = false;
}
cell.getPreelectionList().clear();
}
}
control.setOver(isOver);
control.setOverCount(overCount);
return control;
}
/**
* 返回预选字段最大长度
* @param table
* @return
*/
private int calc(Table table){
List<Row> rows = table.getItems();
int maxLength = 0;
for (int i = 0; i < rows.size(); i++) {
Row row = rows.get(i);
for (int j = 0; j < row.size(); j++) {
Cell cell = row.get(j);
if(cell.getNum() == null){
compare(table, cell);
int size = cell.toPreelection().length();
if(size > maxLength){
maxLength = size;
}
}
}
}
return maxLength;
}
/**
* 将现有数据与自造数据进行比较
* @param table
* @param cell
* @return
*/
private void compare(Table table,Cell cell){
List<Row> items = table.getItems();
//获取当前行
Row row = items.get(cell.getPoint().getRowIndex());
//获取当前单元格的九宫格范围
Map<String,Integer> rangeMap = table.queryLattice(cell);
int rowStrat = rangeMap.get(Constant.ROW_START_RANGE);
int rowEnd = rangeMap.get(Constant.ROW_END_RANGE);
int cellStrat = rangeMap.get(Constant.CELL_START_RANGE);
int cellEnd = rangeMap.get(Constant.CELL_END_RANGE);
for (int i = 1; i <= Constant.LEN; i++) {
boolean equals = false;
//比较行
for (int j = 0; j < row.size(); j++) {
Integer num = row.get(j).getNum();
if(num != null && num.equals(i)){
equals = true;
break;
}
}
if(equals == true){
continue;
}
//比较列
for(int j = 0; j < items.size(); j ++){
Cell c = items.get(j).get(cell.getPoint().getCellIndex());
Integer num = c.getNum();
if(num != null && num.equals(i)){
equals = true;
break;
}
}
if(equals == true){
continue;
}
//比较九宫格
for (int j = rowStrat; j <= rowEnd; j++) {
boolean con = false;
Row r = table.getItems().get(j);
for (int j2 = cellStrat; j2 <= cellEnd; j2++) {
Integer num = r.get(j2).getNum();
if(num != null && num.equals(i)){
con = true;
break;
}
}
if(con == true){
equals = true;
break;
}
}
//保存候选数字
if(equals == false){
cell.addPreelectionNum(i);
}
}
}
}
计算内容了。
package com.mt.snippet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Table {
private List<Row> table;
/**
* 初始化添加N个行
*/
public Table(){
table = new ArrayList<Row>();
for (int i = 0; i < Constant.LEN; i++) {
table.add(new Row());
}
}
public List<Row> getItems() {
return table;
}
public int size() {
return table.size();
}
/**
* 设置指定行内容
* @param index
* @param row
*/
public void setRow(int index,Row row) {
this.table.remove(index);
this.table.set(index, row);
}
/**
* 根据当前单元格,查询当前单元格所在的9宫格
* @param cell
* @return
*/
public Map<String,Integer> queryLattice(Cell cell){
int rowIndex = cell.getPoint().getRowIndex();
int cellIndex = cell.getPoint().getCellIndex();
Map<String,Integer> rangeMap = new HashMap<String,Integer>();
Integer[] rowRange = getRange(rowIndex);
Integer[] cellRange = getRange(cellIndex);
rangeMap.put(Constant.ROW_START_RANGE, rowRange[0]);
rangeMap.put(Constant.ROW_END_RANGE, rowRange[1]);
rangeMap.put(Constant.CELL_START_RANGE, cellRange[0]);
rangeMap.put(Constant.CELL_END_RANGE, cellRange[1]);
return rangeMap;
}
private Integer[] getRange(int index){
Integer[] range = new Integer[2];
if(index <= 2){
range[0] = 0;
range[1] = 2;
}else if(index <= 5){
range[0] = 3;
range[1] = 5;
}else if(index <= 8){
range[0] = 6;
range[1] = 8;
}
return range;
}
/**
* 初始化指定单元格内容
* @param rowIndex
* @param cellIndex
* @param value
*/
public void initData(int rowIndex,int cellIndex,Integer value){
Row row = this.table.get(rowIndex);
Cell cell = row.get(cellIndex);
Point point = new Point(rowIndex,cellIndex);
cell.setPoint(point);
cell.setNum(value);
}
public void print(){
StringBuffer sb = new StringBuffer();
for (int i = 0; i < table.size(); i++) {
Row row = table.get(i);
for (int j = 0; j < row.size(); j++) {
Cell cell = row.get(j);
String m = cell.getNum() == null ? "-" : cell.getNum().toString();
sb.append(m).append(" ");
}
sb.append("\r\n");
}
System.out.println(sb);
}
public void printPreelection(int maxLength){
StringBuffer sb = new StringBuffer();
for (int i = 0; i < table.size(); i++) {
Row row = table.get(i);
for (int j = 0; j < row.size(); j++) {
Cell cell = row.get(j);
String m = appendSpace(maxLength, cell);
sb.append(m);
}
sb.append("\r\n");
}
System.out.println(sb);
}
public String appendSpace(int maxLength,Cell cell){
StringBuffer sb = new StringBuffer();
String m = "";
int len = 0;
boolean isPreelection = cell.getNum() == null ? true : false;
if(true == isPreelection){
m = cell.toPreelection();
}else{
m = cell.getNum().toString();
}
len = m.length();
sb.append(m);
for (int i = 0; i < maxLength - len; i++) {
sb.append(" ");
}
sb.append("|");
return sb.toString();
}
}
转载于:https://blog.51cto.com/hyssmt/1244680