2012-04-11 86 views
2

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

主要方法:

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

的直接原因您的代码不工作是ArrayUnorderedList#contains()大概依靠equals()方法来判断条目在列表中。没有看到班级的定义就不可能知道。

因为你没有提供的equals()的覆盖,它的使用对象标识(从Object默认值),所以每WordNode每个其它WordNode不同。

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

但是,您应该考虑使用Map<String,Integer>(或Map<String,WordNode>)来代替频率。这会更快。

+0

这就是我认为(每个对象是不同的,所以没有比较的话),但我不确定如何制作,所以只会比较单词,并且可能会改变相关对象。不幸的是,我不知道如何实现'WordNode#equals()',因为我们的类从来没有谈论过这个。我也不知道地图是什么,虽然我不怀疑它会更容易。 – lollercopter 2012-04-11 20:44:38

+0

相反 - 我知道如何实现equals方法,但是我应该比较单词还是其他值?另外,当我重写该方法时,是否调用该方法而不是'contains()'?或者我可以让'contains()'使用我的新方法? – lollercopter 2012-04-11 20:46:23

+0

“equals()”的意思是比较对你的特定类重要的事情。在这种情况下,它可能只是返回单词本身的String#equals()的结果。哦,你也应该实现'hashCode()',在这种情况下返回'WordNode.word'的哈希码。 – 2012-04-11 20:49:17

0

你需要重写eqauls在WordNode:

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对象具有相同的字符串作为词场这样,他们被认为是等于

如何调用等号:

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

+0

我已经实现了你的代码,但我是n ow遇到错误:'线程中的异常“main”java.lang.ClassCastException:[Ljava.lang.Object;不能转换为[LWordNode;'。为什么会这样呢? – lollercopter 2012-04-11 21:00:01

+0

请观看我的编辑! – 2012-04-11 21:07:27

+0

我已经实现这个代码的方式是这样的,方法覆盖'contains()'通常的'equals()'方法,如上所述。它如何不能在两个'WordNode'对象上运行?我真的不明白哪里出错,因为我认为这个方法已经有两个'WordNode'对象(传递给方法和'this'的对象)。作为参考,我将这个方法包含在'WordNode'类中。 – lollercopter 2012-04-11 21:54:29