【问题标题】:hash table does not count values correctly哈希表无法正确计算值
【发布时间】:2018-02-01 15:17:43
【问题描述】:

在这里,我正在尝试实现链式哈希表。在这里,当我输入相同的键时,它会与现有键连接并为值加一。我得到的问题是,当我打印最终表格时,它给出了错误的值。每次都有一个键,而其他相同的键正在连接在一起。

插入函数编码如下。

 public void insert (String key, int value){

        int hashValue= generateHashValue(key); //find what bucket suits for each key


        if(table[hashValue] == null) {
            table[hashValue] = new HashTableLinked(key, value);//enter new key           
        }

        else{
            HashTableLinked entry = table[hashValue];
            boolean condition =false;

            while (entry.next!= null){

                if (entry.getKey().equals(key)) {

                    entry.setValue(entry.getValue()+1);  //trying to add +1 for existing key 
                    condition = true;
                    break;
                }

                entry = entry.next;
            }
            if(!condition) {
                entry.next = new HashTableLinked(key, value);
            }        
        }


    } 

如果需要,hashTableLinked 类如下,

public class HashTableLinked {

   private String key;
     int value;
     HashTableLinked next;

   public HashTableLinked(String key,int value){
     this.key = key;
     this.value = value;
     this.next = null;

   public void setValue(int value) {
     this.value = value;
   }

   public String getKey() {
      return key;
   }
   public int getValue(){
     return value;
  }
}

当我输入包含 5 个“the”s 的输入行时

We the People the the the of freedom in Order to form the

输出是

Bucket 9 : the  4 
           the  1 

【问题讨论】:

  • 你调试过你的代码吗?有什么理由实现自己的哈希表而不是使用 Java 的?
  • 这是作业吗?
  • 对不起,如果没有足够的代码可以运行,很难猜出问题出在哪里,例如方法 generateHashValue(key) 在这里没有描述。 {table} 属性也是如此。
  • 我认为代码的另一部分是不必要的..因为它包含更多行..@Kamil...
  • 这是一种家庭作业..但它不是你认为的家庭作业:) @JPRLCol

标签: java hashtable


【解决方案1】:

尽管在 if 语句中已经完成了检查:

while (entry.next!= null) {

应该是

while (entry != null) {

您可以消除 if 语句,注意在循环之后条目为空。

        HashTableLinked entry = table[hashValue];
        boolean found = false;
        HashTableLinked priorEntry = null;
        while (entry != null) {
            if (entry.getKey().equals(key)) {
                entry.setValue(entry.getValue() + 1);  //trying to add +1 for existing key 
                found = true;
                break;
            }
            priorEntry = entry;
            entry = entry.next;
        }
        if (!found) {
            if (priorEntry == null) {
                table[hashValue] = new HashTableLinked(key, value);
            } else {
                priorEntry.next = new HashTableLinked(key, value);
            }
        }        

确实很尴尬。最好在前面插入:

        boolean found = false;
        for (HashTableLinked entry = table[hashValue]; entry != null; entry = entry.next) {
            if (entry.getKey().equals(key)) {
                entry.setValue(entry.getValue() + 1);  // trying to add 1 for existing key 
                found = true;
                break;
            }
        }
        if (!found) {
            HashTableLinked added = new HashTableLinked(key, value);
            added.next = table[hashValue];
            table[hashValue] = added;
        }        

【讨论】:

  • 不需要priorEntry来查找要添加的最后一个元素。
  • 非常感谢。它起作用了.. :) ..为什么总是最好插入前面?减少时间?
【解决方案2】:

看看你的循环:

//This will be the first entry for that bucket
HashTableLinked entry = table[hashValue];
boolean condition =false;

//What happens when the bucket only contains one entry? The loop won't get executed
while (entry.next!= null){
  if (entry.getKey().equals(key)) {
    entry.setValue(entry.getValue()+1);  //trying to add +1 for existing key 
    condition = true;
    break;
  }
  entry = entry.next;
}

//If the loop doesn't get executed, condition will be false
if(!condition) {
  entry.next = new HashTableLinked(key, value);
} 

这意味着当您添加相同的键时,您的代码将创建一个新条目,然后原始条目将在循环中更新。

你要做的是检查entry本身是否为空,而不是是否有下一个条目。

顺便说一句,这应该很容易通过使用调试器单步执行代码来发现。

【讨论】:

  • @roch.p 仔细阅读:第三次添加密钥时循环执行。第一次你将在if(table[hashValue] == null) 分支中,第二次while (entry.next!= null) 不会进行一次迭代,因为entry.next 将立即为空。这就是为什么您会获得 2 个条目以及为什么除了一个(第二个)计数之外的所有计数都添加到第一个条目。
猜你喜欢
  • 1970-01-01
  • 2016-06-23
  • 2015-08-16
  • 2017-02-28
  • 1970-01-01
  • 1970-01-01
  • 2014-04-01
  • 2013-10-30
  • 1970-01-01
相关资源
最近更新 更多