摘要
有一個單詞列表,一個初始單詞和一個最終單詞。初始單詞需要通過單詞列表逐步變換到最終單詞,一個單詞一次只能改變一個字母,求變換所需的最短變換路徑長度。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/************************************
**
** @Description 求根據給定單詞到最終單詞,一次變換一個字母的最短路徑
**
** @author 何明勝
**
** @Date 2017-04-02 18:52:17
**
** @Copyright Copyright (c) 2017
**
************************************/
/************************************
*
* @Modification 優化細節,去掉上一次比較表,單詞列表裏每當一個單詞被遍歷後即標記爲 -1
*
* @version 1.0.1
*
* @author 何明勝
*
* @Date 2017-04-03 23:31:25
*
************************************/
public class WordChange {
private String word_start;//初始單詞
private String word_end;//結束單詞
private String []word_list;//單詞列表
private int length_min = 0;//最小長度
private Boolean is_over = false;//遍歷是否結束
public void init(){
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
//讀取數據
word_start = scanner.nextLine();
word_end = scanner.nextLine();
word_list = scanner.nextLine().split(" ");
}
public void start(){
/*
* 採用廣度優先遍歷
* 爲防止比較時,因與上一次變換的單詞只相差一個字母造成死循環,將上一次用來比較的所有單詞賦值爲 -1
* 每一次遍歷後,最短路徑數加1
*
* 開始遍歷:
* 每一次遍歷,把單詞列表中與當前當前單詞過渡表的每一個單詞比較,再次找出所有隻相差一個字母的單詞
* 最短路徑數加1
* 如果該單詞等於最終單詞,結束遍歷。
* 否則存爲//word_tra
* 且將該單詞置爲-1
*/
List<String> word_tra_temp = new ArrayList<String>();
word_tra_temp.add(word_start);
//開始遍歷
BFTraversal(word_tra_temp);
}
//廣度優先遍歷
public void BFTraversal(List<String> word_tra){
//定義當前單詞過渡表//word_tra_temp
List<String> word_tra_temp = new ArrayList<String>();
for(int i=0; i<word_tra.size(); i++){
//如果該單詞等於最終單詞,結束遍歷
if(is_over){
break;
}
for(int j=0; j<word_list.length; j++){
//判斷該單詞與單詞列表中的單詞是否只差一個字母
if(diffOneChar(word_tra.get(i), word_list[j])){
//如果該單詞等於最終單詞,輸出結果,結束標誌爲true
if(word_list[j].equals(word_end)){
System.out.println(length_min+1);
is_over = true;
break;
}
//否則將單詞添加到暫存表,用於下一次遍歷
word_tra_temp.add(word_list[j]);
//且將該單詞置爲-1
word_list[j] = "-1";
}
}
//錯誤處理
if(length_min == 5000){
is_over = true;
System.out.println("輸入有誤,已經遍歷5000次");
}
if(!is_over){
//最短路徑數加1
length_min++;
//繼續遍歷
BFTraversal(word_tra_temp);
}
}
}
//判斷兩個單詞是否只相差一個字母
public boolean diffOneChar(String str1, String str2){
int is_one = 0;//判斷標誌
//分別對每一個字母判斷,若不同,判斷標誌加1
for(int i=0; i<str1.length(); i++){
if(str1.charAt(i) != str2.charAt(i)){
is_one++;
}
if(is_one > 1){
return false;
}
}
return true;
}
public static void main(String[] args) {
WordChange wordChange = new WordChange();
wordChange.init();//讀入數據
wordChange.start();//開始執行
}
}