今天看见一个数独问题,思考了一个上午居然没有写出来,我的暴脾气一下上来,写了个程序把它干掉了。
数组规则不懂百度,现在讲一下思路
拿到一篇数独
第一步:找一下每一个空白框中可能出现的数字的集合,查看数字集合长度是否大于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();
}
}