目前能够解出简单的数独,用于交流使用,欢迎大家吐槽,现在贴出代码。

程序入口:

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();
    }
}