Java 通过一次更改1个字母进行单词转换

Java 通过一次更改1个字母进行单词转换,java,breadth-first-search,Java,Breadth First Search,我已经编写了一个程序,它将显示一个单词是否可以通过一次更改一个字符来转换为另一个单词,而中间的单词也是有效的单词 例如CAT->COT->DOT->DOC 当我使用LinkedHashSet表示顶点时,该程序工作 但当我使用HashSet时,它会进入一个无限循环或错误答案 我想知道问题是什么,如果有更好的方法解决问题,请告诉我 代码如下:分为3个文件: Graph.java import java.util.ArrayList; import java.util.HashSet; import

我已经编写了一个程序,它将显示一个单词是否可以通过一次更改一个字符来转换为另一个单词,而中间的单词也是有效的单词

例如CAT->COT->DOT->DOC

当我使用
LinkedHashSet
表示顶点时,该程序工作 但当我使用
HashSet
时,它会进入一个无限循环或错误答案

我想知道问题是什么,如果有更好的方法解决问题,请告诉我

代码如下:分为3个文件: Graph.java

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;

public class Graph {

    private Set<GraphNode> vertices;

    public Graph() {
        //the code runs when I use LinkedHashSet
        vertices = new LinkedHashSet<>();
        //the code goes into infinite loop or wrong answer when I use HashSet to represent the vertices
        //************

        //vertices = new HashSet<>();

        //*************
        //^^^^^ strange behaviour
    }

    /**
     * adds all the words from the given dictonary to the graph
     * @param dictonary
     * @return
     */
    public boolean addAll(Set<String> dictonary){
        boolean result= false;

        for (String word : dictonary){
            addNode(word);
        }
        return result;
    }

    /**
     * add a single node into the graph
     * @param data
     * @return
     */
    public GraphNode addNode(String data){
        GraphNode node = new GraphNode();
        node.setValue(data);
        vertices.add(node);
        return node;
    }

    /**
     * add a neighbour to the "source" node
     * @param source
     * @param neighbour
     * @return
     */
    public boolean addNeighbour(GraphNode source, GraphNode neighbour) {
        boolean result = false;
        source.getNeighbours().add(neighbour);
        return result;
    }

    /**
     * This method assigns the neighbours of nodes depending on whether they are one edit
     * away or not
     */
    public void assignNeighbours(){

        ArrayList<GraphNode> listOfNodes = getAllVertices();

        Set<String> usedWords = new HashSet<>();
        for ( int i=0 ;i <listOfNodes.size() ;i++){
            String currentWord = listOfNodes.get(i).value;
            for (int j=0 ; j < listOfNodes.size() ;j++ ){
                if (currentWord.equals(listOfNodes.get(j).value)==false){
                    if (oneEditAway(currentWord, listOfNodes.get(j).value) && usedWords.contains(listOfNodes.get(j).value)==false){
                        listOfNodes.get(i).neighbours.add(listOfNodes.get(j));
                        //reflective 
                        listOfNodes.get(j).neighbours.add(listOfNodes.get(i));
                        usedWords.add(listOfNodes.get(j).value);
                    }
                }
            }
        }
    }

    public ArrayList<GraphNode> getAllVertices(){
        return new ArrayList<>(vertices);
    }

    /**
     * This method determines whether 2 strings are one edit away or not
     * @param first
     * @param second
     * @return
     */
    public  boolean oneEditAway(String first, String second) {
        // TODO Auto-generated method stub
        if (first == null || second == null)
            return false;
        if (Math.abs(first.length() - second.length())>1){
            return false;
        }else{
            int firstLength = first.length();
            int secondLength = second.length();
            int mismatchCount = 0;
            for (int i=0 ;i < firstLength && i < secondLength ; ++i){
                if (first.charAt(i) != second.charAt(i)){
                    mismatchCount++;
                }
            }
            if (mismatchCount > 1 || Math.abs(firstLength - secondLength) == 1){
                return false;
            }
            return true;
        }
    }

    /**
     * This method prints the graph and the connections
     */
    public void printGraph() {
        // TODO Auto-generated method stub
        for (GraphNode node :vertices){
            System.out.println("Node is :"+node.value);
            System.out.println("Neighbours are :");
            for (GraphNode graphNode : node.getNeighbours()){
                System.out.print(graphNode.value+ " ");
            }
            System.out.println();
        }
    }

    /**
     * This function determines whether a word can be transformed into an another or not
     * @param source
     * @param dest
     * @return
     */
    public boolean canTransform(String source, String dest) {
        boolean result = false;


        Set<GraphNode> visited = new HashSet<>();

        //BFS is the way to go
        Queue<GraphNode> allNodes = new LinkedList<>();
        GraphNode root=null;
        //find the source node in the graph
        for (GraphNode node : vertices){
            if (node.value.equals(source)){
                root = node;
            }
        }
        allNodes.add(root);
        System.out.println("***************");
        while(!allNodes.isEmpty()){

            GraphNode currentNode = allNodes.poll();

            System.out.println(currentNode.value);
            visited.add(currentNode);
            if (currentNode.value.equals(dest)){
                result = true;
                break;
            }
            for (GraphNode node: currentNode.getNeighbours()){
                if (visited.contains(node) == false){
                    allNodes.add(node);
                }
            }
        }
        return result;
    }

    @Override
    public String toString() {
        return "Graph  is as follows :\nvertices=" + vertices + "";
    }

    public Set<GraphNode> getVertices() {
        return vertices;
    }
    public void setVertices(Set<GraphNode> vertices) {
        this.vertices = vertices;
    }
    }
import java.util.ArrayList;
导入java.util.HashSet;
导入java.util.LinkedHashSet;
导入java.util.LinkedList;
导入java.util.Queue;
导入java.util.Set;
公共类图{
私有集顶点;
公共图(){
//代码在我使用LinkedHashSet时运行
顶点=新的LinkedHashSet();
//当我使用HashSet表示顶点时,代码进入无限循环或错误答案
//************
//顶点=新的HashSet();
//*************
//^^^^^奇怪的行为
}
/**
*将给定口述词中的所有单词添加到图表中
*@param命令
*@返回
*/
公共布尔addAll(设置命令){
布尔结果=假;
for(字符串字:听写式){
addNode(word);
}
返回结果;
}
/**
*将单个节点添加到图形中
*@param数据
*@返回
*/
公共图形节点addNode(字符串数据){
GraphNode节点=新GraphNode();
节点设置值(数据);
顶点。添加(节点);
返回节点;
}
/**
*将邻居添加到“源”节点
*@param源
*@param邻居
*@返回
*/
公共布尔addNeighbor(GraphNode源,GraphNode邻居){
布尔结果=假;
source.getneights().add(neighter);
返回结果;
}
/**
*此方法根据节点是否为一个编辑节点来分配节点的邻居
*走还是不走
*/
公共图书馆{
ArrayList listOfNodes=getAllVertices();
Set usedWords=new HashSet();
对于(int i=0;i 1){
返回false;
}否则{
int firstLength=first.length();
int secondLength=second.length();
整数不匹配计数=0;
对于(int i=0;i1 | | Math.abs(firstLength-secondLength)==1){
返回false;
}
返回true;
}
}
/**
*此方法打印图形和连接
*/
公共void printGraph(){
//TODO自动生成的方法存根
对于(GraphNode节点:顶点){
System.out.println(“节点为:“+Node.value”);
System.out.println(“邻居是:”);
for(GraphNode GraphNode:node.getNeights()){
System.out.print(graphNode.value+“”);
}
System.out.println();
}
}
/**
*此函数确定一个单词是否可以转换为另一个单词
*@param源
*@param dest
*@返回
*/
公共布尔canTransform(字符串源、字符串目标){
布尔结果=假;
Set visted=新HashSet();
//BFS是一条路要走
Queue allNodes=new LinkedList();
GraphNode root=null;
//在图中查找源节点
对于(GraphNode节点:顶点){
if(node.value.equals(源)){
根=节点;
}
}
添加(根节点);
System.out.println(“*******************”);
而(!allNodes.isEmpty()){
GraphNode currentNode=allNodes.poll();
System.out.println(currentNode.value);
add(currentNode);
if(currentNode.value.equals(dest)){
结果=真;
打破
}
for(GraphNode节点:currentNode.GetNeights()){
if(已访问.包含(节点)=false){
添加(节点);
}
}
}
返回结果;
}
@凌驾
公共字符串toString(){
return“图形如下:\nvertices=“+顶点+”;
}
公共集getVertices(){
返回顶点;
}
公共无效集合顶点(集合顶点){
这个。顶点=顶点;
}
}

下面是GraphNode.java

import java.util.HashSet;
import java.util.Set;

public class GraphNode {

    String value;

    Set<GraphNode> neighbours =  new HashSet<GraphNode>();

    public GraphNode() {
        // TODO Auto-generated constructor stub
    }

    public GraphNode(String value) {
        super();
        this.value = value;
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((value == null) ? 0 : value.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        GraphNode other = (GraphNode) obj;
        if (value == null) {
            if (other.value != null)
                return false;
        } else if (!value.equals(other.value))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "GraphNode [value=" + value + ", neighbours=" + neighbours + "]";
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public Set<GraphNode> getNeighbours() {
        return neighbours;
    }

    public void setNeighbours(Set<GraphNode> neighbours) {
        this.neighbours = neighbours;
    }

}
import java.util.HashSet;
导入java.util.Set;
公共类图形节点{
字符串值;
Set neights=newhashset();
公共图形节点(){
//TODO自动生成的构造函数存根
}
公共图形节点(字符串值){
超级();
这个值=值;
}
@凌驾
公共int hashCode(){
最终整数素数=31;
int结果=1;
result=prime*result+((value==null)?0:value.hashCode();
返回结果;
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(getClass()!=obj.getClass())
返回false;
GraphNode other=(GraphNode)obj;
如果(值==null){
if(other.value!=null)
返回false;
}如果(!value.equals(other.value))
返回false;
返回true;
}
@凌驾
公共字符串toString(){
返回“GraphNode[value=“+value+”,neights=“+neights+”];
}
公共字符串getValue(){
返回值;
}
公共无效设置值(Strin)
import java.util.HashSet;
import java.util.Set;

public class GraphMain {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Graph graph = new Graph();
        Set<String> dict = new HashSet<>();
        dict.add("CAT");
        dict.add("COT");
        dict.add("DOT");
        dict.add("DOG");
        dict.add("DOC");
        graph.addAll(dict);
        graph.assignNeighbours();
        graph.printGraph();
        String source="CAT",dest = "DOC";
        System.out.println("can transform from "+source+" to "+dest+" ??"+graph.canTransform(source,dest));
    }
}
public void assignNeighbours(){
    for ( GraphNode w1: vertices ){
        for ( GraphNode w2: vertices ){
            if (! w1.equals(w2) ){
                if (oneEditAway(w1.getValue(), w2.getValue())){
                    w1.neighbours.add(w2);
                    //reflective 
                    w2.neighbours.add(w1);
                }
            }
        }
    }
}