2

我现在正在进行的项目涉及我从文本文件中读取单词并将它们加载到数组中(最终是二叉树,但这将在稍后完成)。我必须将单词和单词的频率(最初为 1)都加载到数组中,因此我将两个变量都打包到一个 objectWordNode中。我能够将单词加载到数组中,但是当我尝试检查单词是否已经在数组中时,事情就崩溃了。如果是,我必须将频率增加 1。但是,我的代码甚至不检查单词,而是简单地添加它(我假设它正在检查对变量的引用而不是单词本身)。下面是我的main方法和WordNode课程。

主要方法:

public class Driver {
/////////////// fields ///////////////
public static ArrayUnorderedList<WordNode> wordArray = new ArrayUnorderedList<WordNode>();
public static LinkedBinarySearchTree<WordNode> wordTree = new LinkedBinarySearchTree<WordNode>();   //tree to hold words

/////////////// methods ///////////////
public static void main(String[] args) throws Exception {
    //ask for filename       
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    System.out.println("Enter the name of the file to read from: ");
    Reader file = new FileReader(reader.readLine());

    //read file
    Scanner input = new Scanner(file);

    while(input.hasNext()) {
        //get words from file
        String word = input.next();

        //remove non-word characters and convert to lowercase
        word = word.replaceAll("\\W", "");
        word = word.toLowerCase();

        //create node
        WordNode newWord = new WordNode(word);

        //if word is already in array
        if(wordArray.contains(newWord)) {
            System.out.println("Word is already in array");

            //increment frequency by 1
            int index = wordArray.find(newWord);
            wordArray.list[index].setFrequency(wordArray.list[index].getFrequency() + 1);
            System.out.println(newWord.getWord() + newWord.getFrequency());
        } else {
            System.out.println("Word is not yet in array");

            //add word to tree
            System.out.println(newWord.getWord());
            wordArray.addToRear(newWord);
        }
    }

    //insert into tree

    //perform traversals on tree
}

WordNode 类:

public class WordNode {
   protected String word;
   protected WordNode left, right;
   protected int frequency;

   /**
    * Creates a new node with the specified data.
    * @param obj the element that will become a part of the new node
    */
   WordNode(String obj) {
      word = obj;
      left = null;
      right = null;
      frequency = 1;
   }

   /**
    * Gets the word.
    * @return the word
    */
   public String getWord() {
      return word;
   }

   /**
    * Sets the word.
    * @param word the word to set
    */
   public void setWord(String word) {
      this.word = word;
   }

   /**
    * Gets the left.
    * @return the left
    */
   public WordNode getLeft() {
      return left;
   }

   /**
    * Sets the left.
    * @param left the left to set
    */
   public void setLeft(WordNode left) {
      this.left = left;
   }

   /**
    * Gets the right.
    * @return the right
    */
   public WordNode getRight() {
      return right;
   }

   /**
    * Sets the right.
    * @param right the right to set
    */
   public void setRight(WordNode right) {
      this.right = right;
   }

   /**
    * Gets the frequency.
    * @return the frequency
    */
   public int getFrequency() {
      return frequency;
   }

   /**
    * Sets the frequency.
    * @param frequency the frequency to set
    */
   public void setFrequency(int frequency) {
      this.frequency = frequency;
   }
}

ArrayList 类的一些方法:

/**
* Returns true if this list contains the specified element.
* @param target the element that the list is searched for
* @return true if the target is in the list, false if otherwise 
*/
public boolean contains(T target) {
    return (find(target) != NOT_FOUND);
}

/**
* Returns the array index of the specified element, or the
* constant NOT_FOUND if it is not found.
* @param target the element that the list will be searched for
* @return the integer index into the array containing the target element, or the NOT_FOUND constant
*/
public int find(T target) {
    int scan = 0, result = NOT_FOUND;
    boolean found = false;

    if (!isEmpty()) {
       while (!found && scan < rear) {
          if (target.equals(list[scan])) {
              found = true;
          } else {
             scan++;
          }
       }
    }

    if (found) {
       result = scan;
    }

    return result;
}
4

2 回答 2

4

您的代码不起作用的直接原因ArrayUnorderedList#contains()可能是依赖于equals()确定条目是否在列表中的方法。没有看到类的定义是不可能知道的。

由于您没有提供对 的覆盖equals(),因此它使用对象标识(默认来自Object),因此每个WordNode都与其他的不同WordNode

如果要使用,ArrayUnorderedList则必须WordNode#equals()以正确的行为实施。

但是,您应该考虑使用Map<String,Integer>(或Map<String,WordNode>)来存储频率。这会快得多。

于 2012-04-11T20:40:29.217 回答
0

您需要在 WordNode 中覆盖 eqauls:

public boolean equals(Object o) {
     if(o instanceof WordNode) {
        WordNode temp = (WordNode) o;
        return(temp.getWord().equals(this.word));
     }
     else
         System.out.println("Object o you passed is not a WordNode");
}

这样,如果两个不同的 WordNode 对象具有与 word 字段相同的字符串,则它们被视为相等

如何调用等号:

WordNode n1 = new WordNode();
n1.setWord("test");

WordNode n2 = new WordNode();
n2.setWord("test");

System.out.println(n1.equals(n2));

所以 equals 接收一个 Object 类型的对象,但是当你在 WordNode 上调用 equals 时,你必须提供一个作为 WordNode 实例的对象,否则我所做的转换失败(你的例外),当然验证是否没有意义一个对象等于一个 WordNode

于 2012-04-11T20:46:32.460 回答