2012-03-13 2 views
0

Я построил таблицу символов, используя список массивов, заполненный «парами» объектов, которые являются односвязными цепей и удерживают слово и количество раз, которое оно встречается в текстовом файле. Мне нужно использовать это для программы FrequencyCounter, которая подсчитывает количество слов в файле. По какой-то причине, я получаю эту ошибку при запуске на FrequencyCounter с HashST:Реализация таблицы символов хэша Java

Processed 1215985 words (19 sec; 19710 msec 
Exception in thread "main" java.lang.NullPointerException 

at HashST.hashIndex(HashST.java:60) 
at HashST.get(HashST.java:105) 
at FrequencyCounter.main(FrequencyCounter.java:112) 

У меня есть представление о том, что есть что-то не так с моей HashST и его не прикладывая пары в ArrayList, как я хотел к. Будем очень благодарны за любые предложения о том, что не так с реализацией.

Вот мой код и код FrequencyCounter:

import java.util.LinkedList; 
import java.util.ArrayList; 
import java.util.Iterator; 

public class HashST<Key extends Comparable<Key>, Value> implements Iterable<Key> { 
private ArrayList<Pair> chains; 
private int numKeys; 
private int numChains; 


public class Pair 
{ 
    Key key; 
    Value value; 
    Pair(Key k, Value v) 
    { 
     key = k; 
     value = v; 
    } 
    Pair() 
    {} 

    Pair next; 
} 

    /** 
* Initialize an empty HashSt with a default of 64 empty chains. 
*/ 
    public HashST() 
    { 
     this(64); 

    } 

/** 
* Initialize an empty HashST with numChains emptychains. 
* 387911 is a prime number about twice the number of distinct 
* words in the leipzig1M.txt file. 
*/ 
public HashST(int numChains) 
{ 
    this.numChains = numChains; 
    chains = new ArrayList<Pair>(); 

    for(int i = 0; i < numChains; i++) 
    { 
     Pair p = new Pair(null, null); 
     chains.add(p); 

    } 
} 

/** 
* compute the hash index for a key k if the number of 
* chains is N 
*/ 
private int hashIndex(Key k, int N) 
{ 
    return (k.hashCode() & 0x7fffffff) % N; 

} 
/** 
* insert the Pair (k,v) into the appropriate chain and increment 
* the number of keys counter or 
* update the value for k if k is already in the hash table. 
* 
*/ 
public void put(Key k, Value v) { 

    int i = hashIndex(k, numChains); 
    Pair tmp = chains.get(i); 
    if(contains(k)) 
    { 
     while(tmp.next != null) 
     { 
      if(tmp.key == k) 
      { 
       tmp.value = v; 
       return; 
      } 

      tmp = tmp.next; 
     } 
    } 
    else 
    { 
     Pair p = new Pair(k, v); 
     tmp.next = p; 
     numKeys ++; 

    } 




} 

/** 
* return the value for key k if it is in the hash table 
* or else return null if it is not. 
*/ 
public Value get(Key k) { 

    int i = hashIndex(k, numChains); 
    Pair tmp = chains.get(i); 
     while(tmp.next != null) 
     { 
      if(tmp.key == k) 
      { 
       return tmp.value; 

      } 

      tmp = tmp.next; 
     } 


    return null; 

} 

/** 
* remove the pair with key k if it is in the hash table 
* otherwise no change. 
*/ 
public void delete(Key k) { 

    if(contains(k)) 
    { 
     return; 


    } 

} 

/** 
* return true if the hash table contains a pair with key 
* equal to k else return false 
*/ 
public boolean contains(Key k) { 

    return (get(k) != null) ? true : false; 

} 

/** 
* return the number of keys in the hash table 
*/ 
public int size() { 

    return numKeys; 

} 

/** 
* return a LinkedList<Key> containing the keys in the 
* hash table 
*/ 
public Iterable<Key> keys() { 

    LinkedList<Key> l = new LinkedList<Key>(); 
    for(Pair p : chains) 
    { 
     while(p.next != null) 
     { 
      l.add(p.key); 
      p = p.next; 
     } 

    } 


    return l; 
} 

/** 
* return an Iterator<Key> for the keys in the hash table 
*/ 
public Iterator<Key> iterator() { 
    return keys().iterator(); 
} 

} 

А вот Частотомер: http://algs4.cs.princeton.edu/31elementary/FrequencyCounter.java.html

+0

ваш класс 'HashST', но' FrequencyCounter' объявляет объект 'ST'. – Jon

ответ

0

По вашей стеке проследить это, казалось бы линия, кинул нуль указатель:

return (k.hashCode() & 0x7fffffff) % N; 

Таким образом, у нас есть один опорный объект к, целочисленной константой, и примитивный N. ни константа, ни примитивным баллончик null, единственное, что разыменовано здесь, - k. Поэтому похоже, что кто-то пытался получить значение для нулевого k!

+0

Более того, это, скорее всего, связано с тем, как взаимодействуют 'contains()' и 'get()'. 'contains()' похоже, ожидает, что 'get()' будет успешным, но вернет 'null', если ключ отсутствует в таблице. Вместо этого 'get()' терпит неудачу. Чтобы исправить это, вам нужно либо добавить проверку на 'null' в' get() ', либо изменить способ работы' contains() '. – VeeArr

+0

Я в замешательстве. Я думал, что get возвращает null, если ключ отсутствует в таблице. – Offspring47

+0

Похоже, он пытается, но вызывает NullPointerException, вызывая k.hashCode() до того, как он дойдет до этого. – Affe

Смежные вопросы