2012-04-11 84 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

相關問題