Java:如何使这个哈希表函数在更大范围内工作

Java:如何使这个哈希表函数在更大范围内工作,java,string,hash,hashtable,hash-collision,Java,String,Hash,Hashtable,Hash Collision,我有下面的代码,它将获取30个数字字符串,并在使用%29计算它们之后将它们放入哈希表中 import java.util.Arrays; public class HashFunction { String[] theArray; int arraySize; int itemsInArray = 0; public static void main(String[] args) { HashFunction theFunc = new

我有下面的代码,它将获取30个数字字符串,并在使用%29计算它们之后将它们放入哈希表中

import java.util.Arrays;


public class HashFunction {

    String[] theArray;
    int arraySize;
    int itemsInArray = 0;

    public static void main(String[] args) {

        HashFunction theFunc = new HashFunction(30); // this is where you should be able to control the number of spaces availble in the hash table!!!

        // Simplest Hash Function

        // String[] elementsToAdd = { "1", "5", "17", "21", "26" };

        // theFunc.hashFunction1(elementsToAdd, theFunc.theArray);

        // Mod Hash Function
        // This contains exactly 30 items to show how collisions
        // will work

        String[] elementsToAdd2 = { "100", "510", "170", "214", "268", "398",
                "235", "802", "900", "723", "699", "1", "16", "999", "890",
                "725", "998", "978", "988", "990", "989", "984", "320", "321",
                "400", "415", "450", "50", "660", "624" };

        theFunc.hashFunction2(elementsToAdd2, theFunc.theArray);

        // Locate the value 660 in the Hash Table

        //theFunc.findKey("660");

        theFunc.displayTheStack();

    }

    // Simple Hash Function that puts values in the same
    // index that matches their value

    public void hashFunction1(String[] stringsForArray, String[] theArray) {

        for (int n = 0; n < stringsForArray.length; n++) {

            String newElementVal = stringsForArray[n];

            theArray[Integer.parseInt(newElementVal)] = newElementVal;

        }

    }



    public void hashFunction2(String[] stringsForArray, String[] theArray) {

                        int sumOfCollisions = 0;
                        float averageOfCollisions = 0;
                        int numberOfCollisions = 0;                        

        for (int n = 0; n < stringsForArray.length; n++) {

            String newElementVal = stringsForArray[n];

            // Create an index to store the value in by taking
            // the modulus

            int arrayIndex = Integer.parseInt(newElementVal) % 29;

            System.out.println("Modulus Index= " + arrayIndex + " for value "
                    + newElementVal);

            // Cycle through the array until we find an empty space


            while (theArray[arrayIndex] != "-1") {
                ++arrayIndex;
                                numberOfCollisions++;

                //System.out.println("Collision Try " + arrayIndex + " Instead");
                                //System.out.println("Number of Collisions = " + numberOfCollisions);
                // If we get to the end of the array go back to index 0

                arrayIndex %= arraySize;
            }


                        if (numberOfCollisions > 0)
                        {
                            System.out.println("                       Number of Collisions = " + numberOfCollisions);
                        }                       

            theArray[arrayIndex] = newElementVal;

        }

                        sumOfCollisions += numberOfCollisions;

                        averageOfCollisions = sumOfCollisions / 30;

                        System.out.println("Sum of Collisions = " + sumOfCollisions);

                        System.out.println("Average of Collisions = " + averageOfCollisions);                

    }

    // Returns the value stored in the Hash Table

    public String findKey(String key) {

        // Find the keys original hash key
        int arrayIndexHash = Integer.parseInt(key) % 29;

        while (theArray[arrayIndexHash] != "-1") {

            if (theArray[arrayIndexHash] == key) {

                // Found the key so return it
                System.out.println(key + " was found in index "
                        + arrayIndexHash);

                return theArray[arrayIndexHash];

            }

            // Look in the next index

            ++arrayIndexHash;

            // If we get to the end of the array go back to index 0

            arrayIndexHash %= arraySize;

        }

        // Couldn't locate the key

        return null;

    }

    HashFunction(int size) {

        arraySize = size;

        theArray = new String[size];

        Arrays.fill(theArray, "-1");

    }

    public void displayTheStack() {

        int increment = 0;

        for (int m = 0; m < 3; m++) {

            increment += 10;

            for (int n = 0; n < 71; n++)
                System.out.print("-");

            System.out.println();

            for (int n = increment - 10; n < increment; n++) {

                System.out.format("| %3s " + " ", n);

            }

            System.out.println("|");

            for (int n = 0; n < 71; n++)
                System.out.print("-");

            System.out.println();

            for (int n = increment - 10; n < increment; n++) {

                if (theArray[n].equals("-1"))
                    System.out.print("|      ");

                else
                    System.out
                            .print(String.format("| %3s " + " ", theArray[n]));

            }

            System.out.println("|");

            for (int n = 0; n < 71; n++)
                System.out.print("-");

            System.out.println();

        }

    }

}
正如你所看到的,我已经设置好了它,它告诉我在构建这个特定的哈希表时发生的平均冲突数。有30个数字和30个空格供他们使用。我尝试将可用空间量的参数从30更改为60,但这没有改变任何东西,我想知道如何解决这个问题

这对我来说很重要,因为我想把这段代码提高一个档次。我想用这个程序来测试一组更大的数字,可能是1000或更多,但我不想再手动输入1000个字符串数字。我如何编写一个循环来为我实现这一点?例如,如果我在其参数中输入1000,它将以字符串表示法生成1000个数字,如将要使用的代码所示

我还希望这样,我可以在一个程序执行中运行多个字符串。例如,哈希表可以容纳1000个数字,因此它将使用1个数字运行程序,然后使用2,3等等。。。直到它这样做了,一直到1000。对于每次这样做,我希望它输出在特定运行中发生的平均碰撞次数。如果只有1个数字,则不会发生碰撞,并且随着数字数量的增加,最终会发生碰撞

通过这样做,我可以制作一个图表,显示碰撞的数量如何随着可用点的数量比率的变化而变化。例如,x轴是平均碰撞,y轴是输入数量与总可用空间的比率,这意味着它的值范围为0到1.00


提前感谢你花时间教我的一切。我真的很感激。

要让您的程序为您随机生成数字,您应该创建一个方法,该方法接受整数参数,该参数在该大小的数组中循环并插入一个随机数

int size_of_hash = Integer.parseInt( args[1] );
上面的代码将从命令行获取一个参数,并使用它创建一个变量,该变量确定哈希表的大小。可以使用此变量创建哈希函数,也可以使用它创建数组

您可以调用一个方法

public int[] createRandomArray( int size ) {
    Random r = new Random(); //java.util.Random - this class will randomly generate integers for you
     int random_array = //instantiate the array

     for( int i = 0; i <= size; i++ ) {
         //insert logic
      }

      return random_array;
 }
这个方法是不完整的。学习的最好方法就是去做。这里需要注意的重要一点是,这种方法本质上是接受一个简单的重复任务,并让程序为您完成它。Javadocs是了解java生态系统中新资源的一个很好的资源。只要GoogleJavadocRandom,这个类就会出现

我建议将main方法更改为类的构造函数,并重写main方法以调用可以在程序参数中指定的大量试验。这将有助于通过运行大量试验(而不是一次试验)获得更准确的数据。

使用以下方法:

import java.util.Random; //that's where it is.
...
...//directly to the class
private Random r = new Random();
public String randomString(int limit)
{
    int n = r.nextInt(limit);
    return n+"";
}
...
这将返回一个字符串形式的随机数,该字符串在limit0到limit-1之间。 如果您想要一个n位数的字符串,请执行此操作

StringBuilder s = new StringBuilder();
for(int i = 0; i < n; i++)
    s.append(r.nextInt(10));
return s.toString();

你试过使用随机类吗?没有,我没有试过。你认为这在这里行吗?我可以使用random类在一组特定的数字参数内创建一个随机数字字符串吗?我不想得到负片,或者数字超过1000。请稍等。我稍后再回答。是的,你可以生成非负数且在一定范围内的随机数。但我的数字不是真正的数字,对吗?它们是弦。所以我不确定你会如何实施。如果你知道怎么做,请告诉我。不要使用randomStringint 1000;,使用随机序列1000;谢谢你的意见,这很有帮助。我已经实现了您的建议,我有一个问题,关于何时在读取字符串[]elementsToAdd2={}的部分实际输入值。我试着把它放入这样的循环中:对于int I=0;您是否将elementsToAdd2声明为String elementsToAdd2[]=新字符串[30]?您必须提供一个大小,并在for循环中使用elementsToAdd2.length而不是30;而不是randomStringint 1000;,但是现在它声明elementsToAdd2已经定义,仍然有一个错误到“tring[]elementsToAdd2=新字符串[30];”,并将'30'更改为'elementsToAdd2.length',但我仍然得到错误。另外,我认为我应该在for循环中将'String[]'更改为'String[I]',当我这样做时,错误会变为说a;是意料之中的事,整行都不是陈述。具体地说,它表示找不到该符号变量字符串。
StringBuilder s = new StringBuilder();
for(int i = 0; i < n; i++)
    s.append(r.nextInt(10));
return s.toString();