繁体   English   中英

如何修复Java哈希表声明错误?

how to fix java hashtable assertion error?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我必须实现一个哈希表,该哈希表可以通过针对课程作业的设置测试,我已经设法通过了所有测试,但只有两个,并且无法弄清为什么未通过测试。 两种测试均给出断言错误。 他们测试了get和put方法。

下面是整个哈希表代码,因为我认为该错误可能是另一种方法。

哈希表代码:

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;

public class Hashtable<V> {

private Object[] arr; //an array of Pair objects, where each pair contains the key and value stored in the hashtable
private int max; //the size of arr. This should be a prime number
private int itemCount; //the number of items stored in arr
private final double maxLoad = 0.6; //the maximum load factor

public static enum PROBE_TYPE {
    LINEAR_PROBE, QUADRATIC_PROBE, DOUBLE_HASH;
}

PROBE_TYPE probeType; //the type of probe to use when dealing with collisions
private final BigInteger DBL_HASH_K = BigInteger.valueOf(8);

/**
 * Create a new Hashtable with a given initial capacity and using a given probe type
 * @param initialCapacity
 * @param pt
 */
public Hashtable(int initialCapacity, PROBE_TYPE pt) {
    max = nextPrime(initialCapacity);
    probeType = pt ;
    arr = new Object[max];
}

/**
 * Create a new Hashtable with a given initial capacity and using the default probe type
 * @param initialCapacity
 */
public Hashtable(int initialCapacity) {
    max = nextPrime(initialCapacity);
    probeType = PROBE_TYPE.LINEAR_PROBE;
    arr = new Object[max];
}

/**
 * Store the value against the given key. If the loadFactor exceeds maxLoad, call the resize 
 * method to resize the array. the If key already exists then its value should be overwritten.
 * Create a new Pair item containing the key and value, then use the findEmpty method to find an unoccupied 
 * position in the array to store the pair. Call findEmmpty with the hashed value of the key as the starting
 * position for the search, stepNum of zero and the original key.
 * containing   
 * @param key
 * @param value
 */

public void put(String key, V value) {  
    int i = hash(key);
    int finalPos = findEmpty(i,1, key);
    
    if (this.getLoadFactor() > this.maxLoad) {
        this.resize();
    }
    
    if (!hasKey(key)) {
        itemCount++;
    }
    
    arr[finalPos] = new Pair(key, value);   
}

/**
 * Get the value associated with key, or return null if key does not exists. Use the find method to search the
 * array, starting at the hashed value of the key, stepNum of zero and the original key.
 * @param key
 * @return
 */
public V get(String key) {
    int i = hash(key);
    
    if( arr[i] == null) {
        return null;
    } else {return find(hash(key),key,0);}
}

/**
 * Return true if the Hashtable contains this key, false otherwise 
 * @param key
 * @return
 */
public boolean hasKey(String key) {
    if (find(hash(key),key,0) == null) {
        return false;
    }else {
        return true;
    }
}

/**
 * Return all the keys in this Hashtable as a collection
 * @return
 */
public Collection<String> getKeys() {
    ArrayList<String> collection = new ArrayList<String>();
    for(int i =0;i<arr.length;i++) {
        if(arr[i] != null) {
            Pair p = (Pair) arr[i];
            collection.add(p.key);
        }
    }
    return collection;
}

/**
 * Return the load factor, which is the ratio of itemCount to max
 * @return
 */
public double getLoadFactor() {
    return itemCount / (double) max;
}

/**
 * return the maximum capacity of the Hashtable
 * @return
 */
public int getCapacity() {
    return this.max;
}

/**
 * Find the value stored for this key, starting the search at position startPos in the array. If
 * the item at position startPos is null, the Hashtable does not contain the value, so return null. 
 * If the key stored in the pair at position startPos matches the key we're looking for, return the associated 
 * value. If the key stored in the pair at position startPos does not match the key we're looking for, this
 * is a hash collision so use the getNextLocation method with an incremented value of stepNum to find 
 * the next location to search (the way that this is calculated will differ depending on the probe type 
 * being used). Then use the value of the next location in a recursive call to find.
 * @param startPos
 * @param key
 * @param stepNum
 * @return
 */
private V find(int startPos, String key, int stepNum) {
    Pair p = (Pair) arr[startPos];
    if(p == null) {
        return null;
        
    }else if (p.key.equals(key)) {
        return p.value;
        
    }else {
        stepNum++;
        int nextLocation = getNextLocation(startPos, stepNum, key);
        return find(nextLocation, key , stepNum);
    }
}

/**
 * Find the first unoccupied location where a value associated with key can be stored, starting the
 * search at position startPos. If startPos is unoccupied, return startPos. Otherwise use the getNextLocation
 * method with an incremented value of stepNum to find the appropriate next position to check 
 * (which will differ depending on the probe type being used) and use this in a recursive call to findEmpty.
 * @param startPos
 * @param stepNum
 * @param key
 * @return
 */
private int findEmpty(int startPos, int stepNum, String key) {
    if (arr[startPos] == null || ((Pair) arr[startPos]).key.equals(key)) {
        return startPos;
    }else {
        stepNum++;
        int nextPos = getNextLocation(startPos,stepNum,key);
        return findEmpty(nextPos,stepNum,key);
    }       
}

/**
 * Finds the next position in the Hashtable array starting at position startPos. If the linear
 * probe is being used, we just increment startPos. If the double hash probe type is being used, 
 * add the double hashed value of the key to startPos. If the quadratic probe is being used, add
 * the square of the step number to startPos.
 * @param i
 * @param stepNum
 * @param key
 * @return
 */
private int getNextLocation(int startPos, int stepNum, String key) {
    int step = startPos;
    switch (probeType) {
    case LINEAR_PROBE:
        step++;
        break;
    case DOUBLE_HASH:
        step += doubleHash(key);
        break;
    case QUADRATIC_PROBE:
        step += stepNum * stepNum;
        break;
    default:
        break;
    }
    return step % max;
}

/**
 * A secondary hash function which returns a small value (less than or equal to DBL_HASH_K)
 * to probe the next location if the double hash probe type is being used
 * @param key
 * @return
 */
private int doubleHash(String key) {
    BigInteger hashVal = BigInteger.valueOf(key.charAt(0) - 96);
    for (int i = 0; i < key.length(); i++) {
        BigInteger c = BigInteger.valueOf(key.charAt(i) - 96);
        hashVal = hashVal.multiply(BigInteger.valueOf(27)).add(c);
    }
    return DBL_HASH_K.subtract(hashVal.mod(DBL_HASH_K)).intValue();
}

/**
 * Return an int value calculated by hashing the key. See the lecture slides for information
 * on creating hash functions. The return value should be less than max, the maximum capacity 
 * of the array
 * @param key
 * @return
 */
private int hash(String key) {
    int hashVal = key.charAt(0);
    for(int i=0; i<key.length();i++) {
        int c = key.charAt(i);
        hashVal =(hashVal * 27 +c) % max;
    }
    return hashVal;
}

/**
 * Return true if n is prime
 * @param n
 * @return
 */
private boolean isPrime(int n) {
    if(n<=2) return true;
    if(n % 2 == 0) return false;
    for(int i=3; i*i<n; i+=2) {
        if(n % i == 0) return false;
    }
    return true;
}

/**
 * Get the smallest prime number which is larger than n
 * @param n
 * @return
 */
private int nextPrime(int n) {
    if(isPrime(n)) {
        return n;
    }else {
        n++;
        return nextPrime(n);
    }
}

/**
 * Resize the hashtable, to be used when the load factor exceeds maxLoad. The new size of
 * the underlying array should be the smallest prime number which is at least twice the size
 * of the old array.
 */
private void resize() {
        int tableSize = nextPrime(max*2);
        Object[] oldArr = arr;
        arr = new Object[tableSize];
        itemCount = 0;
        max = tableSize;
        for (int i=0;i<oldArr.length;i++) {
            if(oldArr[i] != null) {
                Pair p = (Pair) oldArr[i];
                put(p.key, p.value);
            }
            
        }
}


/**
 * Instances of Pair are stored in the underlying array. We can't just store
 * the value because we need to check the original key in the case of collisions.
 * @author jb259
 *
 */
private class Pair {
    private String key;
    private V value;

    public Pair(String key, V value) {
        this.key = key;
        this.value = value;
    }
}

}

测试:

@Test
public void testInsert() {
    Hashtable<Boolean> h = new Hashtable<>(1000, PROBE_TYPE.DOUBLE_HASH);
    for(int i=0;i<2000;i++) {
        for(int j=2000;j>0;j--) {
            h.put(i+":"+j, true);
        }
    }
    
    for(int i=0;i<2000;i++) {
        for(int j=2000;j>0;j--) {
            assertTrue(h.hasKey(i+":"+j));
        }
    }
}

    @Test
public void testGet() {
    Hashtable<String> h = new Hashtable<>(9);
    int c = 0;
    for(int i=0;i<10;i++) {
        for(int j=10;j>0;j--) {
            h.put(i+":"+j, j+":"+i);
            c++;
        }
    }
    for(int i=0;i<10;i++) {
        for(int j=10;j>0;j--) {
            assertEquals(h.get(i+":"+j), j+":"+i);
        }
    }
}

非常感谢您的帮助!!

问题暂未有回复.您可以查看右边的相关问题.
1 如何在C中修复'mremap块断言错误'

我目前正在学习C,并且正在尝试将可用内存量扩展到一系列结构。 当我尝试增加数组时,在运行时收到以下错误 这是引起问题的代码。 我曾尝试阅读realloc手册页和在线教程,但无法找到解决此特定情况的任何方法。 我期望数组可以扩展为三个大小,以便以后可以添加其他元素,但是我仍 ...

2019-02-01 01:28:28 1 84   c
2 如何修复“断言'__pos <= size'失败”错误?

我正在尝试编写一个函数来比较两个字符串,比如s1和s2 ,如果在某个位置, s1[i] == s2[i] ,那么它必须将计数器加一(即它计算数字在相同位置(例如i )的情况下,它们包含相同的字符)。 我正在使用的代码: #include &lt;iostream&gt; #include &lt; ...

3 如何修复MongoDB致命断言28595错误?

我正在尝试使mongo服务器在docker容器中启动并运行,但出现错误: 运行以下命令可以启动服务器,并且可以在docker容器外部进行访问: 但是当执行以下命令时,Mongo将上述错误日志记录到日志文件中 不确定为什么会导致此问题。 请帮助。 谢谢你。 ...

4 如何在异步声明中修复Mocha错误格式

我正在尝试使用Mocha 2.4.5和Should.js 8.3.0设置浏览器内测试。 失败应该断言显示有用的测试失败原因。 但是,当在jQuery Ajax回调的上下文中进行相同的声明时,我会收到一个Uncaught Assertion Error 。 请看以下示例: ...

5 如何修复和断言在测试文件中引发的错误

编写一个递归函数 displayFiles,它需要一个路径名作为参数。 路径名可以是文件名或目录名。 如果路径名引用一个文件,则显示其文件路径,后跟其内容,如下所示: 这就是我所拥有的 这是错误: 这是测试文件: 断言错误不再是问题,但现在有一个 NotADirectoryError ...

2021-10-25 13:44:44 0 32   python
6 Java-如何在哈希表中处理哈希表

我目前正在尝试使用SAX编写XML解析器,并希望将XML文件的元素保存到Hashtable中,但是为此,我需要在第一个表中再添加一个(如下所示): 我的问题是是否有可能解决第二个哈希表,如果可以,我该怎么做? ...

9 如何修复C ++中的ffmpeg'Assertion error'错误

我正在编写一个程序来加速视频的安静部分,我想支持长达2小时的视频。 这适用于基于命令行的程序。 我在XCode中构建它,然后将编译的程序复制到带有输入视频的文件夹并从终端运行它。 我基本上是根据来自ffmpeg的silence_detect特性的时间生成一个运行非常大的复杂滤波器的 ...

10 如何在Java中随机播放哈希表

我在一个类中有一个构造函数,在其中初始化一个哈希表,该哈希表由一个整数和一个字符串列表组成。 我用从0到所需数字的数字填充键,它们的对应值是我预先在构造函数中创建的Vector。 我需要的是随机重新排列它们(只要以任何可能的方式随机排列它们),这样当我使用getQuest()时,我将得到一个 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM