使用程序解决数独问题

今天看见一个数独问题,思考了一个上午居然没有写出来,我的暴脾气一下上来,写了个程序把它干掉了。

数组规则不懂百度,现在讲一下思路

拿到一篇数独

第一步:找一下每一个空白框中可能出现的数字的集合,查看数字集合长度是否大于0,是就做第二步,不是则return;

第二步:将数字集合按照长度从小到大排序(这样有利于找到答案)

第三步:第一个元素中的集合是否为空,不为空放置一个数返回第一步,如果为空则return;

两个文件:一个输入文件名字为shudu.txt,一个输出文件名字为mylog.txt

输入文件的内容为:

得到的结果为

程序如下:

package problem;

import java.io.*;
import java.util.*;

public class ShuDu {
    /**
     * 解决数组问题
     *
     * @param args
     */
    private int[][] a = null;

    public ShuDu() {
        a = new int[9][];
        for (int i = 0; i < 9; i++) {
            a[i] = new int[9];
            for (int j = 0; j < 9; j++) {
                a[i][j] = 0;
            }
        }
    }

    /**
     * 输入函数
     */
    public void input() {
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
        String str = null;
        try {
            fileReader = new FileReader("shudu.txt");
            bufferedReader = new BufferedReader(fileReader);
            int row = 0;
            while ((str = bufferedReader.readLine()) != null) {
                for (int i = 0; i < 9; i++) {
                    this.a[row][i] = str.charAt(i) - '0';
                }
                row++;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 输出函数
     */
    public void output() {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                System.out.printf("%d ", this.a[i][j]);
            }
            System.out.println();
        }
    }

    /**
     * 得到有用的集合
     *
     * @param i
     * @param j
     * @return
     */
    public HashSet<Integer> getUseful(int i, int j) {
        HashSet<Integer> result = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
        HashSet<Integer> used = new HashSet<>();
        //小方框中的集合
        int blockRow = i / 3;
        int blockCol = j / 3;
        for (int t = 0; t < 3; t++) {
            for (int k = 0; k < 3; k++) {
                used.add(this.a[blockRow * 3 + t][blockCol * 3 + k]);
            }
        }

        //这一行的集合
        for (int t = 0; t < 9; t++) {
            used.add(this.a[i][t]);
        }
        //这一列的集合
        for (int k = 0; k < 9; k++) {
            used.add(this.a[k][j]);
        }
        result.removeAll(used);
//        System.out.println(result);
        return result;
    }

    /**
     * 开始处理
     */
    public void deal_help() {
        //得到所有的集合
        HashMap<Vector<Integer>, Set<Integer>> map = new HashMap<>();
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (this.a[i][j] == 0) {
                    Vector<Integer> v = new Vector<>(Arrays.asList(i, j));
                    Set<Integer> s = getUseful(i, j);
                    map.put(v, s);
                }
            }
        }
//        System.out.println(map.size());
        if (map.size() == 0) {
            output();
        }
        //按照集合从小到大的顺序排列
        LinkedHashMap linkedHashMap = sortByValue(map);
        //进行放置
        Iterator<Map.Entry<Vector<Integer>, Set<Integer>>> iterator = linkedHashMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<Vector<Integer>, Set<Integer>> item = iterator.next();
            Vector<Integer> v = item.getKey();
            Set<Integer> s = item.getValue();
            if (s.size() == 0) {
                return;
            }
            for (int valueItem : s) {
                this.a[v.get(0)][v.get(1)] = valueItem;
                deal_help();
                this.a[v.get(0)][v.get(1)] = 0;
            }
            break;
        }
    }

    /**
     * 对集合按值的长度排序的方法
     *
     * @param oriMap
     * @return
     */
    public static LinkedHashMap<Vector<Integer>, Set<Integer>> sortByValue(HashMap<Vector<Integer>, Set<Integer>> oriMap) {
        LinkedHashMap<Vector<Integer>, Set<Integer>> sortMap = new LinkedHashMap<>();
        List<Map.Entry<Vector<Integer>, Set<Integer>>> entryList = new ArrayList<>(oriMap.entrySet());
        Collections.sort(entryList, new MapValueComparator());
        Iterator<Map.Entry<Vector<Integer>, Set<Integer>>> iterator = entryList.iterator();
        Map.Entry<Vector<Integer>, Set<Integer>> tmp = null;
        while (iterator.hasNext()) {
            tmp = iterator.next();
            sortMap.put(tmp.getKey(), tmp.getValue());
        }
        return sortMap;
    }

    public static void main(String[] args) {
        PrintStream ps = null;
        try {
            ps = new PrintStream("mylog.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        System.setOut(ps);
        ShuDu s = new ShuDu();
        s.input();
        s.deal_help();
    }
}

/**
 * 比较器
 */
class MapValueComparator implements Comparator<Map.Entry<Vector<Integer>, Set<Integer>>> {

    @Override
    public int compare(Map.Entry<Vector<Integer>, Set<Integer>> o1, Map.Entry<Vector<Integer>, Set<Integer>> o2) {

        return o1.getValue().size() - o2.getValue().size();
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值