校招編程題(二) 字符串變換之廣度優先遍歷

摘要
有一個單詞列表,一個初始單詞和一個最終單詞。初始單詞需要通過單詞列表逐步變換到最終單詞,一個單詞一次只能改變一個字母,求變換所需的最短變換路徑長度。


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();//開始執行
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章