每天刷個演算法題20160526:BFS解決八數碼問題(九宮格問題)
版權所有。所有權利保留。
歡迎轉載,轉載時請註明出處:
http://blog.csdn.net/xiaofei_it/article/details/51524864
為了防止思維僵化,每天刷個演算法題。已經刷了幾天了,現在發點程式碼。
我已經建了一個開源專案,每天的題目都在裡面:
https://github.com/Xiaofei-it/Algorithms
絕大部分演算法都是我自己寫的,沒有參考網上通用程式碼。讀者可能會覺得有的程式碼晦澀難懂,因為那是我自己的理解。
最近幾天都是在寫一些原來的東西,大多數是非遞迴。以後準備刷點DP、貪心之類的題。
下面是BFS解決八數碼問題,這個其實應該用A*演算法,但我今天練一下BFS,以後再寫一個A*的版本。
/**
*
* Copyright 2016 Xiaofei
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package xiaofei.algorithm;
import java.util.ArrayList;
import java.util.HashSet;
/**
* Created by Xiaofei on 16/5/26.
*
* 八數碼問題,也就是九宮格問題。按理說要用A*演算法,這個很久以前寫過。我以後再寫。
*
* 今天只是想練練BFS。
*
* 這個英文不知道該怎麼說,Eight digit maze是我自己瞎寫的。
*
* 9的9次方,可以用int表示。int是4位元組。
*
* 如果用其他方式表示,比如一個位元組表示兩個格,好像都沒int省空間。
*
* 所以就用int。
*/
public class EightDigitMaze {
private static int[] dx = new int[]{0, 0, -1, 1};
private static int[] dy = new int[]{-1, 1, 0, 0};
private static int arrayToInt(int[][] array) {
int result = 1;
for (int i = 0; i < 3; ++i) {
final int[] subArray = array[i];
for (int j = 0; j < 3; ++j) {
result = result * 9 + subArray[j];
}
}
return result;
}
private static int[][] intToArray(int x) {
int[][] result = new int[3][3];
for (int i = 2; i >= 0; --i) {
for (int j = 2; j >= 0; --j) {
result[i][j] = x % 9;
x /= 9;
}
}
return result;
}
private static void output(int x) {
int[][] array = intToArray(x);
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (array[i][j] == 0) {
System.out.print(' ');
} else {
System.out.print(array[i][j]);
}
}
System.out.println();
}
}
/**
*
* 下面這個函式很長,因為我把所有的東西都放裡面了。為什麼不變成子函式?因為變成子函式的話很蛋疼。
*
* 我這個專案都是演算法,不是工程,所以不用管那麼多程式碼風格。
*/
public static void solve(int[][] source, int[][] dest) {
class Element {
int state;
int last;
Element(int state) {
this.state = state;
this.last = -1;
}
Element(int state, int last) {
this.state = state;
this.last = last;
}
}
HashSet<Integer> set = new HashSet<>();
final int sourceInt = arrayToInt(source);
final int destInt = arrayToInt(dest);
set.add(sourceInt);
//如果用Queue,我不知道怎麼儲存之前的資料,所以這裡直接用ArrayList
ArrayList<Element> queue = new ArrayList<>();
int head = 0;
int tail = 1;
queue.add(new Element(sourceInt));
while (head < tail) {
Element element = queue.get(head);
if (element.state == destInt) {
//輸出結果,退出迴圈。
ArrayList<Integer> tmp = new ArrayList<>();
int index = head;
while (index != -1) {
tmp.add(index);
index = queue.get(index).last;
}
final int size = tmp.size();
for (int i = size - 1; i >= 0; --i) {
System.out.println("Step " + Integer.toString(size - i));
output(queue.get(tmp.get(i)).state);
}
break;
}
int[][] array = intToArray(element.state);
boolean flag = false;
int x = -1, y = -1;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (array[i][j] == 0) {
flag = true;
x = i;
y = j;
break;
}
}
if (flag) {
break;
}
}
for (int i = 0; i < 4; ++i) {
int nextX = x + dx[i];
int nextY = y + dy[i];
if (0 <= nextX && nextX <= 2 && 0 <= nextY && nextY <= 2) {
int tmp = array[nextX][nextY];
array[nextX][nextY] = 0;
array[x][y] = tmp;
int state = arrayToInt(array);
if (!set.contains(state)) {
queue.add(new Element(state, head));
set.add(state);
++tail;
}
array[nextX][nextY] = tmp;
array[x][y] = 0;
}
}
++head;
}
}
}
相關文章
- Java解世界最難九宮格問題Java
- 回溯法解決迷宮問題
- 每天刷個演算法題20160519:回溯法解八皇后演算法
- 八數碼 經典問題
- 用C語言解決迷宮問題C語言
- 解決「問題」,不要解決問題
- 使用A*演算法解迷宮最短路徑問題演算法
- 人工智慧之八數碼問題人工智慧
- 發現問題,解決問題
- (BFS廣度優先演算法) 油田問題演算法
- 解決SSH亂碼問題
- 解決中文亂碼問題
- 解決問題
- 華為優招面試題---迷宮問題面試題
- 雙模數問題 題解
- 解決Url帶中文引數亂碼問題
- js解八皇后問題程式碼例項JS
- java解決數字黑洞問題Java
- 提問題比解決問題更重要
- Hive 刷題——獎金瓜分問題Hive
- 用C語言實現八數碼問題C語言
- 回溯法(排列樹)解決八(N)皇后問題
- 解決八種Linux硬碟問題的技巧Linux硬碟
- 今天解決的兩個問題
- MySql中文亂碼問題解決MySql
- Jmeter 解決中文亂碼問題JMeter
- Java 解決中文亂碼問題Java
- RDSSQLSERVER解決中文亂碼問題SQLServer
- 解決MySQL中文亂碼問題MySql
- MYSQL亂碼問題解決方法MySql
- 回溯法求迷宮問題
- POJ3984-迷宮問題
- yum問題解決
- sqlitedabaseislocked問題解決SQLite
- dump 解決問題
- 【問題解決】單機搭建dataguard的問題
- js解決url傳引數中文亂碼問題JS
- nginx 直播程式數問題(待解決)Nginx