校招编程题(二) 字符串变换之广度优先遍历

摘要
有一个单词列表,一个初始单词和一个最终单词。初始单词需要通过单词列表逐步变换到最终单词,一个单词一次只能改变一个字母,求变换所需的最短变换路径长度。


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 word_tra_temp = new ArrayList();
        word_tra_temp.add(word_start);

        //开始遍历
        BFTraversal(word_tra_temp);
    }

    //广度优先遍历 
    public void BFTraversal(List word_tra){
        //定义当前单词过渡表//word_tra_temp
        List word_tra_temp = new ArrayList();

        for(int i=0; i//如果该单词等于最终单词,结束遍历
            if(is_over){
                break;
            }

            for(int j=0; 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; iif(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();//开始执行
    }
}

你可能感兴趣的:(校招编程题)