java數獨生成演算法(遞迴)
阿新 • • 發佈:2019-02-04
..... ArrayList<JTextField> list = new ArrayList<JTextField>(); // 數獨的格子 ArrayList<ArrayList<Integer>> insertArray = new ArrayList<ArrayList<Integer>>(); /** * <li> 生成一個隨機的填滿的數獨 * private void solution(int index, ArrayList<ArrayList<Integer>> insertArray) * <p><p><P> 描述: 通過遞迴的方式生成一個隨機的填滿的數獨,實現原理是首先通過傳入的下標判斷當前位置是否有可以填入 * 的數字,如果有將當前數字填入,並將當前的可填入的數字的集合(出去已經填入的數字)儲存到方法的另一個引數ArrayList<ArrayList<Integer>> insertArray * 中,再遞迴。否則嘗試修改前一個座標的下的填入的數字,如果前一個座標下的對應的ArrayList<ArrayList<Integer>> insertArray中的ArrayList<Integer>中還有可 * 插入的數字則修改前一個座標下的數字,再遞迴,否則將前一個位置中的內容置空,將遞迴起點指定到前一位置,然後遞迴。(其中,如果當前位置上的ArrayList<ArrayList<Integer>> insertArray * 中包含了當前位置的可插入數字的集合,則表示本次遞迴為上次插入不成功導致的,所以將該數字的集合當做當前可插入的數字的集合,這樣一方面可以減少重複判斷的次數 * 提高程式碼效率,同時使程式碼邏輯合理) * @param index list的下標 * @param insertArray 可插入數字的集合(已經去掉已插入的)的集合 */ private void solution(int index, ArrayList<ArrayList<Integer>> insertArray) { if (index>80) return; else { ArrayList<Integer> insert = insertable(index/9, index%9); if (insertArray.size()>index) insert = insertArray.remove(index); // 次步驟非常關鍵, if (insert.size()>0) { list.get(index).setText(insert.remove(0).toString()); insertArray.add(insert); solution(++index, insertArray); // dg } else { --index; ArrayList<Integer> preInsert = insertArray.get(index); if (preInsert.size()>0) { list.get(index).setText(insertArray.get(index).remove(0).toString()); solution(++index, insertArray); // dg } else { list.get(index).setText(""); solution(index, insertArray); //dg } } } } /** * description:隨機生成 from-to 的整數 * @param from 從哪個數字開始 * @param to 到哪個數字結束 * @return (int) 隨機數 */ private int randomNum(int from, int to) { return from + (int) (Math.random()*(to-from+1)); } /** * description: 獲取當前位置可填入的數字 * @param indexI 行座標 * @param indexJ 列座標 * @return base 可填入的數字的集合 */ private ArrayList<Integer> insertable(int indexI, int indexJ) { ArrayList<Integer> base = new ArrayList<Integer>(); for (int i = 1; i <= 9; i++) base.add(i); Collections.shuffle(base); String str = null; // 判斷區填入 int regionI = (indexI/3)*3; int regionJ = (indexJ/3)*3; for (int i = regionI; i < regionI+3; i++) { for (int j = regionJ; j < regionJ+3; j++) { str = list.get(i*9+j).getText(); // 之後base中只剩下該區中可填的數字 if (str!=null&&!str.equals("")) { if (base.contains(Integer.parseInt(str))) base.remove(base.indexOf(Integer.parseInt(str))); } } } // 判斷行填入 for (int j = 0; j < 9; j++) { str = list.get(indexI*9+j).getText(); // 之後base中只剩下行中可填入的數字 if (str!=null&&!str.equals("")) { if (base.contains(Integer.parseInt(str))) base.remove(base.indexOf(Integer.parseInt(str))); } } // 判斷列填入 for (int i = 0; i < 9; i++) { str = list.get(i*9+indexJ).getText(); // 之後base中只剩下列中可填入的數字 if (str!=null&&!str.equals("")) { if (base.contains(Integer.parseInt(str))) base.remove(base.indexOf(Integer.parseInt(str))); } } base.trimToSize(); return base; }