Java字梯形图程序输出堆栈溢出错误

时间:2016-12-08 17:23:52

标签: java stack-overflow

我必须在java中编写用于字梯程序的代码。说明如下:

  

使用递归编写程序以找到给出的字梯   开始单词和结束单词,或确定是否存在单词梯形图。   使用文件“words.txt”作为有效单词的字典。这个   该文件包含87314个单词。你的程序不需要找到   单词之间最短的字梯,任何单词梯都会做到   存在。

     

例如,从FISH开始,您可以制作一个字梯到MAST   通过以下梯子:
  FISH,WISH,WASH,MASH,MAST

以下是words.txt

的链接

我觉得我的代码非常接近工作,但我的输出上出现了堆栈溢出错误:

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)

我的代码如下:

import 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个字母的单词。

非常感谢任何帮助让它正确运行。

2 个答案:

答案 0 :(得分: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");
    }
}

答案 1 :(得分:-1)

将此方法用于&#34; findTheWord&#34;你会得到你想要的结果

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