排序列表的分配

时间:2010-11-23 05:02:28

标签: java sortedlist

我非常接近完成,但不能完全弄清楚如何将所有东西捆绑在一起。我有单独的方法负责他们的特定任务,但我觉得我的凝聚力非常糟糕。不确定它们如何结合在一起以及需要在主要部分中调用什么。这里的目标是从命令行中读取文本文件,并按字典顺序列出故事中的单词。

% java Ten < story.txt
Word      Occurs
====      ======
a          21
animal      3
 .
 .
 .
zebra       1
%

到目前为止,这是我的代码:

import java.util.Scanner;

public class Ten2
{
    public static void main(String [] arg)
    {
        Scanner input = new Scanner(System.in);

        String word;
        List sortedList = new List();
        word = nextWord(input);

        while (word!=null) {
            sortedList.insert(word);
            word = nextWord(input);
        }

        sortedList.printWords();        
    }

    private static String nextWord(Scanner input)
    {   
        // return null if there are no more words
        if (input.hasNext() == false )
            return null;
        // take next element, convert to lowercase, store in s
        else { 
            String s = input.next().toLowerCase() ;
            // empty string
            String token = "";
            // loop through s and concatonate chars onto token
            for (int i =0; i < s.length(); i++) {
                if (Character.isLetter(s.charAt(i)) == true)
                    token = token + s.charAt(i);
                else if (s.charAt(i) == '\'' )
                    token = token + s.charAt(i);
                else if (s.charAt(i) == '-')
                    token = token + s.charAt(i);
            }
            return token; 
        }      
    }   
}

class List
{
    /*
     * Internally, the list of strings is represented by a linked chain 
     * of nodes belonging to the class ListNode. The strings are stored
     * in lexicographical order.
     */
    private static class ListNode
    {
        // instance variables for ListNode objects
        public String word;
        public ListNode next;
        public int count;

        // Listnode constructor               
        public ListNode(String w, ListNode nxt)
        {  
            word = w; // token from nextWord()?
            next = nxt; // link to next ListNode
            count = 1; // number of word occurences
        }
    }

    // instance variables for List object
    private ListNode first;
    private int numWords;

    // constructor postcondition: creates new Listnode storing object
    public List()
    { 
        first = null; // pointer to ListNode?
        numWords = 0; // counter for nodes in list
    }


    //  Insert a specified word into the list, keeping the list 
    //  in lexicographical order.
    public void insert(String word)
    {    
        // check if first is null
        if (first == null) {
            ListNode newNode;
            newNode = addNode(word, null);
            first = newNode;          
        }   

        // else if (first is not null) check if word matches first word in List
        else if (word.equals(first.word)) {
            // increase count
            first.count++;
            }

        // else (first is not null && doesn't match first word) 
        else {  
            ListNode newNode;
            ListNode current;
            current = first;
            ListNode previous;
            previous = null;
            int cmp =  word.compareTo(current.word);

            /*
             * Fist two cases of empty list and word already existing
             * handled in above if and else statements, now by using compareTo() 
             * method between the words, the insertion postion can be determined.
             * Links between ListNode variables current and previous need to be
             * modified in order to maintain the list
             */


            // loop as long as value comparing to is positive
            // when compareTo() returns positive this means the "word" parameter is greater than the word in the list 
            while ((cmp >0) && (current.next != null)) {
                previous = current;    
                current = current.next;
                cmp =  word.compareTo(current.word);
            }

            // insert after current at end of list
            if ((cmp >0 && current.next == null)) {
                newNode = addNode(word, null);
                current.next = newNode;
            }

            // increments count when word already exists
            else if (cmp==0) {
                current.count++;
            }

            // else (cmp < 0) we insert BEFORE current
            else { 
                newNode = addNode(word, current);

                // first node in list comes after new word
                if (previous == null) {
                    first = newNode;       
                }         

                else {
                    // inserting new word in middle of list
                    previous.next = newNode;
                }
            }       
        }
    }

    // method to add new ListNode and increase counter
    private ListNode addNode(String word, ListNode next)
    {
        ListNode newNode = new ListNode(word, next);
        numWords++;
        return newNode;
    }


    // Returns a string array that contains all the words in the list.  
    public String[] getWords() 
    {
        String[] Words = new String[numWords];
        ListNode current = first;
        int i =0;

        while (current != null) {     
            Words[i] = current.word;
            current = current.next;
            i++;
        }
        return Words;
    }   


    // Returns an int array that contains the number of times 
    // each word occurs in the list.  
    public int[] getNumbers()
    {
        int[] Numbers = new int[numWords];
        ListNode current = first;
        int i =0;

        while (current != null) {
            Numbers[i] = current.count;
            current = current.next;
            i++;
        }
        return Numbers;
    }


    // Outputs the string array and int array containing all the   
    // words in the list and the number of times each occurs.
    public void printWords()
    {
        int[] Numbers = getNumbers();
        String[] Words = getWords();

        System.out.println("Word   \t    \t    Occurs");
        System.out.println("====   \t    \t    ======");

        for (int i =0; i < numWords; i++) { 
            System.out.println(Words[i] + " \t " + Numbers[i]);   
        }
    }      
}   

2 个答案:

答案 0 :(得分:3)

好吧,我首先要定义你希望你的程序做什么,你已经完成了:

  

此处的目标是从命令行中读取文本文件,并按字典顺序列出故事中的单词。

你的主要功能是几乎。基本上,你需要的是一个将它绑在一起的循环:

public static void main(String [] arg)
{
    // print out your initial information first (i.e. your column headers)
    // ...

    List sortedList = new List();
    String word = nextWord();

    // now, the question is... what is the end condition of the loop?
    // probably that there aren't any more words, so word in this case
    // will be null
    while (word != null)
    {
      sortedList.insert(word);
      word = nextWord();
    }

    // now, your list takes care of the sorting, so let's just print the list
    sortedList.printWords();
}

我认为这就是它的全部。通常情况下,我不喜欢将解决方案发布到家庭作业问题上,但在这种情况下,由于你已经拥有了所有的代码,而你只是需要一点推动才能将你推向正确的方向,我认为这很好。

我注意到有些事情与您的

不一致

您的列表构造函数具有'void'返回类型 - 构造函数上应该没有返回类型:

public List() //make an empty list
{ 
    first = null;
    numWords = 0;
}

此方法中的'else'语句不需要:

    public static String nextWord()
    {   
        if ( keyboard.hasNext() == false )
            return null;
        else {   
            String start =  keyboard.next().toLowerCase() ;
            String organized = "";
            for (int i =0; i < start.length(); i++) {
                if (Character.isLetter(start.charAt(i)) == true)
                    organized = organized + start.charAt(i);

                else if (start.charAt(i) == '\'' )
                    organized = organized + start.charAt(i);

                else if (start.charAt(i) == '-')
                    organized = organized + start.charAt(i);
            }
            return organized;       
        }   
    }

所以,这应该是:

public static String nextWord()
{   
    if ( keyboard.hasNext() == false )
        return null;
    String start =  keyboard.next().toLowerCase() ;
    String organized = "";
    for (int i =0; i < start.length(); i++) {
        if (Character.isLetter(start.charAt(i)) == true)
            organized = organized + start.charAt(i);

        else if (start.charAt(i) == '\'' )
            organized = organized + start.charAt(i);

        else if (start.charAt(i) == '-')
            organized = organized + start.charAt(i);
    }
    return organized;   
}

如果你想使用BufferedReader,这很容易。只需在主方法中进行设置:

  if (arg.length > 0)
  {
    // open our file and read everything into a string buffer
    BufferedReader bRead = null;
    try {
      bRead = new BufferedReader(new FileReader(arg[0]));
    } catch(FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      System.exit(0);
    }
    setupScanner(bRead);
  }

然后,创建一个设置扫描仪对象的新方法:

public static void setupScanner(BufferedReader rdr)
{
  keyboard = new Scanner(rdr);
}

然后在命令行中传入它(即java ten2 [filename])

答案 1 :(得分:0)

    import java.util.Scanner;

public class Ten2
{
    public static void main(String [] arg)
    {
        Scanner input = new Scanner(System.in);

        String word;
        List sortedList = new List();
        word = nextWord(input);

        while (word!=null) {
            sortedList.insert(word);
            word = nextWord(input);
        }

        sortedList.printWords();        
    }

    private static String nextWord(Scanner input)
    {   
        // return null if there are no more words
        if (input.hasNext() == false )
            return null;
        // take next element, convert to lowercase, store in s
        else { 
            String s = input.next().toLowerCase() ;
            // empty string
            String token = "";
            // loop through s and concatonate chars onto token
            for (int i =0; i < s.length(); i++) {
                if (Character.isLetter(s.charAt(i)) == true)
                    token = token + s.charAt(i);
                else if (s.charAt(i) == '\'' )
                    token = token + s.charAt(i);
                else if (s.charAt(i) == '-')
                    token = token + s.charAt(i);
            }
            return token; 
        }      
    }   
}

class List
{
    /*
     * Internally, the list of strings is represented by a linked chain 
     * of nodes belonging to the class ListNode. The strings are stored
     * in lexicographical order.
     */
    private static class ListNode
    {
        // instance variables for ListNode objects
        public String word;
        public ListNode next;
        public int count;

        // Listnode constructor               
        public ListNode(String w, ListNode nxt)
        {  
            word = w; // token from nextWord()?
            next = nxt; // link to next ListNode
            count = 1; // number of word occurences
        }
    }

    // instance variables for List object
    private ListNode first;
    private int numWords;

    // constructor postcondition: creates new Listnode storing object
    public List()
    { 
        first = null; // pointer to ListNode?
        numWords = 0; // counter for nodes in list
    }


    //  Insert a specified word into the list, keeping the list 
    //  in lexicographical order.
    public void insert(String word)
    {    
        // check if first is null
        if (first == null) {
            ListNode newNode;
            newNode = addNode(word, null);
            first = newNode;          
        }   

        // else if (first is not null) check if word matches first word in List
        else if (word.equals(first.word)) {
            // increase count
            first.count++;
            }

        // else (first is not null && doesn't match first word) 
        else {  
            ListNode newNode;
            ListNode current;
            current = first;
            ListNode previous;
            previous = null;
            int cmp =  word.compareTo(current.word);

            /*
             * Fist two cases of empty list and word already existing
             * handled in above if and else statements, now by using compareTo() 
             * method between the words, the insertion postion can be determined.
             * Links between ListNode variables current and previous need to be
             * modified in order to maintain the list
             */


            // loop as long as value comparing to is positive
            // when compareTo() returns positive this means the "word" parameter is greater than the word in the list 
            while ((cmp >0) && (current.next != null)) {
                previous = current;    
                current = current.next;
                cmp =  word.compareTo(current.word);
            }

            // insert after current at end of list
            if ((cmp >0 && current.next == null)) {
                newNode = addNode(word, null);
                current.next = newNode;
            }

            // increments count when word already exists
            else if (cmp==0) {
                current.count++;
            }

            // else (cmp < 0) we insert BEFORE current
            else { 
                newNode = addNode(word, current);

                // first node in list comes after new word
                if (previous == null) {
                    first = newNode;       
                }         

                else {
                    // inserting new word in middle of list
                    previous.next = newNode;
                }
            }       
        }
    }

    // method to add new ListNode and increase counter
    private ListNode addNode(String word, ListNode next)
    {
        ListNode newNode = new ListNode(word, next);
        numWords++;
        return newNode;
    }


    // Returns a string array that contains all the words in the list.  
    public String[] getWords() 
    {
        String[] Words = new String[numWords];
        ListNode current = first;
        int i =0;

        while (current != null) {     
            Words[i] = current.word;
            current = current.next;
            i++;
        }
        return Words;
    }   


    // Returns an int array that contains the number of times 
    // each word occurs in the list.  
    public int[] getNumbers()
    {
        int[] Numbers = new int[numWords];
        ListNode current = first;
        int i =0;

        while (current != null) {
            Numbers[i] = current.count;
            current = current.next;
            i++;
        }
        return Numbers;
    }


    // Outputs the string array and int array containing all the   
    // words in the list and the number of times each occurs.
    public void printWords()
    {
        int[] Numbers = getNumbers();
        String[] Words = getWords();

        System.out.println("Word   \t    \t    Occurs");
        System.out.println("====   \t    \t    ======");

        for (int i =0; i < numWords; i++) { 
            System.out.println(Words[i] + " \t " + Numbers[i]);   
        }
    }      
}