import java.util.PriorityQueue; import textio.TextIO; /** * Makes an alphabetical list of all the words in a file selected * by the user. All words are converted to lower case. The list * of words can be written to a file. The words from the input * file are stored in a PriorityQueue. The effect is that the * words are in alphabetical order, but duplicates are NOT removed * from the list. */ public class WordListWithPriorityQueue { public static void main(String[] args) { System.out.println("\n\nThis program will ask you to select an input file."); System.out.println("It will read that file and make an alphabetical"); System.out.println("list of all the words in the file. After reading"); System.out.println("the file, the program asks you to select an output"); System.out.println("file. If you select a file, the list of words will"); System.out.println("be written to that file; if you cancel, the list will"); System.out.println("be written to standard output. Words are converted to"); System.out.println("lower case. Duplicates are NOT eliminated from the list.\n\n"); System.out.print("Press return to begin."); TextIO.getln(); // Wait for user to press return. try { if (TextIO.readUserSelectedFile() == false) { System.out.println("No input file selected. Exiting."); System.exit(1); } PriorityQueue wordList = new PriorityQueue<>(); // The words from the file. String word = readNextWord(); while (word != null) { // word == null when the end of file is reached. word = word.toLowerCase(); // Convert word to lower case. wordList.add(word); // Adds word to set only if it is not already present. word = readNextWord(); } System.out.println("Number of different words found in file: " + wordList.size()); System.out.println(); if (wordList.size() == 0) { System.out.println("No words found in file."); System.out.println("Exiting without saving data."); System.exit(0); } TextIO.writeUserSelectedFile(); // If user cancels, output automatically // goes to standard output. TextIO.putln(wordList.size() + " words found in file:\n"); while ( ! wordList.isEmpty() ) { TextIO.putln(" " + wordList.remove()); } System.out.println("\n\nDone.\n\n"); } catch (Exception e) { System.out.println("Sorry, an error has occurred."); System.out.println("Error Message: " + e.getMessage()); } System.exit(0); // Might be necessary, because of use of file dialogs. } /** * Read the next word from TextIO, if there is one. First, skip past * any non-letters in the input. If an end-of-file is encountered before * a word is found, return null. Otherwise, read and return the word. * A word is defined as a sequence of letters. Also, a word can include * an apostrophe if the apostrophe is surrounded by letters on each side. * @return the next word from TextIO, or null if an end-of-file is encountered */ private static String readNextWord() { char ch = TextIO.peek(); // Look at next character in input. while (ch != TextIO.EOF && !Character.isLetter(ch)) { TextIO.getAnyChar(); // Read the character. ch = TextIO.peek(); // Look at the next character. } if (ch == TextIO.EOF) // Encountered end-of-file return null; // At this point, we know that the next character is a letter, so read a word. String word = ""; // This will be the word that is read. while (true) { word += TextIO.getAnyChar(); // Append the letter onto word. ch = TextIO.peek(); // Look at next character. if ( ch == '\'' ) { // The next character is an apostrophe. Read it, and // if the following character is a letter, add both the // Apostrophe and the letter onto the word and continue // reading the word. If the character after the apostrophe // is not a letter, the word is done, so break out of the loop. TextIO.getAnyChar(); // Read the apostrophe. ch = TextIO.peek(); // Look at char that follows apostrophe. if (Character.isLetter(ch)) { word += "\'" + TextIO.getAnyChar(); ch = TextIO.peek(); // Look at next char. } else break; } if ( ! Character.isLetter(ch) ) { // If the next character is not a letter, the word is // finished, so break out of the loop. break; } // If we haven't broken out of the loop, next char is a letter. } return word; // Return the word that has been read. } }