2016-12-08 49 views
0

我必须在java中为梯形图程序编写代码。指令如下:Java Word梯形图程序输出堆栈溢出错误

使用递归编写程序来查找给定 开始字和结束字的字梯,或者确定是否不存在字梯。 使用文件“words.txt”作为有效单词的字典。这 文件包含87314个单词。您的程序不需要在单词之间找到最短的单词梯形图,如果有一个单词梯形图将会出现在 之间。

例如,鱼开始你可以做一个字梯通过下面的梯形MAST :
                 鱼,WISH,洗净,捣烂,MAST

这里是链接words.txt

我觉得我的代码非常接近工作,但我getti在我的输出纳克一个堆栈溢出错误:

Exception in thread "main" java.lang.StackOverflowError 
    at java.io.FileOutputStream.write(FileOutputStream.java:326) 
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStrea‌​m.java:82) 
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java‌​:140) 
    at java.io.PrintStream.write(PrintStream.java:482) 
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221) 
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:‌​291) 
    at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104) 
    at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.ja‌​va:185) 

我的代码如下:

进口java.util.Scanner的; import java.io.FileNotFoundException; import java.io.FileInputStream; import java.io.File; import java.io.FileReader; import java.io.PrintWriter; import java.io.FileOutputStream;

public class C11PP8 
{ 
    public static void main(String[] args) 
    { 
    Scanner inputStream = null; 
    PrintWriter outputStream = null; 
    int numWords = 0; 
    String wordRead = ""; 
    String[] wordLibrary; 
    String startWord, endWord; 
    Scanner keyboard = new Scanner(System.in); 
    int i; 


    //open for writing four letter words 
    try 
    { 
     outputStream = new PrintWriter(new FileOutputStream("FourLetterWords.txt")); 
    }//end try 

    catch(FileNotFoundException e) 
    { 
     System.out.println("File not found, program will close."); 
     System.exit(0); 
    }//end catch 


    //open for reading all words 
    try 
    { 
     inputStream = new Scanner(new FileReader("words.txt")); 

    }//end try 

    catch(FileNotFoundException e) 
    { 
     System.out.println("File not found, program will close."); 
     System.exit(0); 
    }//end catch 

    while(inputStream.hasNextLine()) 
    { 
     wordRead = inputStream.nextLine(); 
     if(wordRead.length() == 4) 
     { 
     wordRead = wordRead.toLowerCase(); 
     outputStream.println(wordRead); 
     } 
    }//end while loop 

    inputStream.close(); 
    outputStream.close(); 

    //open for reading to count number of words 
    try 
    { 
     inputStream = new Scanner(new FileReader("FourLetterWords.txt")); 

    }//end try 

    catch(FileNotFoundException e) 
    { 
     System.out.println("File not found, program will close."); 
     System.exit(0); 
    }//end catch 

    while(inputStream.hasNextLine()) 
    { 
     inputStream.nextLine(); 
     ++numWords; 
    }//end while loop 

    inputStream.close(); 

    //declare 
    wordLibrary = new String[numWords]; 

    //open FourLetterWord to read 
    //and populate the array of words 
    try 
    { 
     inputStream = new Scanner(new FileReader("FourLetterWords.txt")); 

    }//end try 

    catch(FileNotFoundException e) 
    { 
     System.out.println("File not found, program will close."); 
     System.exit(0); 
    }//end catch 

    i = 0; 
    while(inputStream.hasNextLine()) 
    { 
     wordLibrary[i] = inputStream.nextLine(); 
     ++i; 
    }//end while loop 

    inputStream.close(); 

    //confirm 
    //for(i = 0; i < wordLibrary.length; ++i) 
    // System.out.println(wordLibrary[i]); 

    //user input 
    do 
    { 
     System.out.println("Enter your 4 letter start word: "); 
     startWord = keyboard.nextLine(); 
    }while(startWord.length() != 4); 
    startWord = startWord.toLowerCase(); 

    do 
    { 
     System.out.println("Enter your 4 letter end word: "); 
     endWord = keyboard.nextLine(); 
    }while(endWord.length() != 4); 
    endWord = endWord.toLowerCase(); 

    //call the recursive method 
    findTheWord(startWord, endWord, wordLibrary); 

    }//end main 

    public static void findTheWord(String startWordPassed, String endWordPassed, String[] libraryPassed) 
    { 
    String currentWord = ""; 
    int count = 0; 
    //base case 
    if(endWordPassed.equals(startWordPassed)) 
    { 
     System.out.println("Word found: " + endWordPassed); 
    }//end if 
    else 
    { 
     //change a single letter of the startWordPassed and make that the new startWordPassed 
     // if the new word is in the array 

     //OR 

     //iterate through the array and find a word that is only one letter different than startWordPassed 
     //make that the new startWordPassed 

     for(int i = 0; i < libraryPassed.length; ++ i) 
     { 
     currentWord = libraryPassed[i]; 
     for(int j = 0; j < startWordPassed.length(); ++ j) 
     { 
      if(startWordPassed.charAt(j) == currentWord.charAt(j)) 
      ++count; 
     }//end for loop 
     if(count == 3) 
     libraryPassed[i] = " "; 
     }//end for loop 
     System.out.println(currentWord); 
     startWordPassed = currentWord; 
     //recursive call 
     findTheWord(startWordPassed, endWordPassed, libraryPassed); 
    }//end else 
    }//end method 

}//end class 

我得到的输出是多个“zuni”的,然后堆栈溢出。 “zuni”是文本文档中的最后4个字母的单词。

任何帮助正确运行这将是不胜感激。

+0

你能提供堆栈跟踪的相关部分吗? –

+0

线程“主”java.lang中的异常。的StackOverflowError \t在java.io.FileOutputStream.write(FileOutputStream.java:326) \t在java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) \t在java.io.BufferedOutputStream.flush(BufferedOutputStream.java: 140) \t在java.io.PrintStream.write(PrintStream.java:482) \t在sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221) \t在sun.nio.cs.StreamEncoder.implFlushBuffer (StreamEncoder.java:291) \t at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104) \t at java.io.OutputStreamWriter.flushBuffer(OutputStr eamWriter.java:185) – Sheriff44

+0

此外,看到这个http://stackoverflow.com/questions/214741/what-is-a-stackoverflowerror在递归'findTheWord'函数调用可能会导致程序用完循环堆栈内存。 –

回答

-1

使用此方法为“findTheWord”,您将得到的结果,你想

public static void findTheWord(String startWordPassed, 
     String endWordPassed, String[] libraryPassed) { 
    String currentWord = ""; 
    int count = 0; 
    // base case 
    if (endWordPassed.equals(startWordPassed)) { 
     System.out.println("Word found: " + endWordPassed); 
    }// end if 
    else { 
     // change a single letter of the startWordPassed and make that the 
     // new startWordPassed 
     // if the new word is in the array 

     // OR 
     Map<String, Integer> index = new HashMap<String, Integer>(); 

     for (int i = 0; i < libraryPassed.length; i++) { 
      index.put(libraryPassed[i], i); 
     } 
     System.out.println("Start Index:" + index.get(startWordPassed)); 
     System.out.println("End Index:" + index.get(endWordPassed)); 
     // iterate through the array and find a word that is only one letter 
     // different than startWordPassed 
     // make that the new startWordPassed 
     System.out.println("Start Word:" + startWordPassed); 
     int startIndex = index.get(startWordPassed) + 1; 
     int endIndex = index.get(endWordPassed); 
     for (int i = startIndex; i < endIndex; i++) { 
      currentWord = libraryPassed[i]; 
      //System.out.println("current word:"+currentWord); 
      count = 0; 
      for (int j = 0; j < startWordPassed.length(); ++j) { 
       if (startWordPassed.charAt(j) == currentWord.charAt(j)) 
        ++count; 
      }// end for loop 
      if (count == 3) 
      { 
       startWordPassed = currentWord; 
       System.out.println("Ladder Word:"+startWordPassed); 
      } 
     }// end for loop 
    }// end else 
}// end method 
+0

为什么限制开始和结束索引之间的搜索区域? – sanastasiadis

+0

我的理解最初是检查2个单词之间的Ladder单词,如果不是这样,可以删除非常简单的end索引 – murthy

+0

startIndex和endIndex是您的代码的主要贡献,那不是解决问题。如果我们删除它们,那么代码将作为问题的代码,导致堆栈溢出。 – sanastasiadis

0

你的递归方法应该按顺序返回东西的程序时,递归需要停止检测。

此外,只有满足条件时才应调用递归方法调用(count == 3)。

替换为您findTheWord()方法:

public static boolean findTheWord(String startWordPassed, String endWordPassed, String[] libraryPassed) 
{ 
    String currentWord = ""; 
    //base case 
    if(endWordPassed.equals(startWordPassed)) 
    { 
     System.out.println("Word found: " + endWordPassed); 
     return true; 
    }//end if 
    else 
    { 
     for(int i = 0; i < libraryPassed.length; ++ i) 
     { 
      currentWord = libraryPassed[i]; 
      int count = 0; 
      for(int j = 0; j < startWordPassed.length(); ++ j) 
      { 
       if(startWordPassed.charAt(j) == currentWord.charAt(j)) 
        ++count; 
      }//end for loop 
      if(count == 3) { 
       libraryPassed[i] = " "; 
       System.out.println(currentWord); 
       startWordPassed = currentWord; 
       //recursive call 
       if (findTheWord(startWordPassed, endWordPassed, libraryPassed)) { 
        return true; 
       } 
      } 
     }//end for loop 
    }//end else 

    return false; 
}//end method 

为了在没有梯子存在,那么你可以在main方法内使用findTheWord()的返回值来覆盖的情况下:

public static void main(String[] args) { 
    ... 
    ... 
    //call the recursive method 
    if (!findTheWord(startWord, endWord, wordLibrary)) { 
     System.out.println("No ladder exists"); 
    } 
} 
+0

谢谢sanastasiadis。我没有考虑创建一个布尔方法,但这是我需要的方式。非常感激。 – Sheriff44

+0

你想接受它作为你在这里的问题的答案吗? – sanastasiadis