I created a hashing method to make a=1, b=2, c=3...etc. To me it doesn't seem too efficient. Does this look efficient or is there a recursive method or smaller method to do the same thing?

/**
 * Changes String to int
 * @param key: String
 * @return (result % arraySize): int
 */
public int hashFunc (String key)
{
int result = 0;
String inputString = key.toString().toLowerCase(); 
// changes String to lowercase
char [] characters = inputString.toCharArray(); // makes String an Array
for (int i = 0; i < characters.length; i++) // loop
{
        char currentChar = characters[i]; // gets current character

        if (currentChar == 'a') 
        { // if character is a
                result += 1;
                // get character numbers
        }// end if
        if (currentChar == 'b') 
        { // if character is b
                result += 2;
                // get character numbers
        }// end if
        if (currentChar == 'c') 
        { // if character is c
                result += 3;
                // get character numbers
        }// end if
        if (currentChar == 'd') 
        { // if character isd
                result += 4;
                // get character numbers
        }// end if
        if (currentChar == 'e') 
        { // if character is e
                result += 5;
                // get character numbers
        }// end if
        if (currentChar == 'f') 
        { // if character is f
                result += 6;
                // get character numbers
        }// end if
        if (currentChar == 'g') 
        { // if character is g
                result += 7;
                // get character numbers
        }// end if
        if (currentChar == 'h') 
        { // if character is h
                result += 8;
                // get character numbers
        }// end if
        if (currentChar == 'i') 
        { // if character is i
                result += 9;
                // get character numbers
        }// end if
        if (currentChar == 'j') 
        { // if character is j
                result += 10;
                // get character numbers
        }// end if
        if (currentChar == 'k') 
        { // if character is k
                result += 11;
                // get character numbers
        }// end if
        if (currentChar == 'l') 
        { // if character is l
                result += 12;
                // get character numbers
        }// end if
        if (currentChar == 'm') 
        { // if character is m
                result += 13;
                // get character numbers
        }// end if
        if (currentChar == 'n') 
        { // if character is n
                result += 14;
                // get character numbers
        }// end if
        if (currentChar == 'o') 
        { // if character is 0
                result += 15;
                // get character numbers
        }// end if
        if (currentChar == 'p') 
        { // if character is p
                result += 16;
                // get character numbers
        }// end if
        if (currentChar == 'q') 
        { // if character is q
                result += 17;
                // get character numbers
        }// end if
        if (currentChar == 'r') 
        { // if character is r
                result += 18;
                // get character numbers
        }// end if
        if (currentChar == 's') 
        { // if character is s
                result += 19;
                // get character numbers
        }// end if
        if (currentChar == 't') 
        { // if character is t
                result += 20;
                // get character numbers
        }// end if
        if (currentChar == 'u') 
        { // if character is u
                result += 21;
                // get character numbers
        }// end if
        if (currentChar == 'v') 
        { // if character is v
                result += 22;
                // get character numbers
        }// end if
        if (currentChar == 'w') 
        { // if character is w
                result += 23;
                // get character numbers
        }// end if
        if (currentChar == 'x') 
        { // if character is x
                result += 24;
                // get character numbers
        }// end if
        if (currentChar == 'y') 
        { // if character is y
                result += 25;
                // get character numbers
        }// end if
        if (currentChar == 'z') 
        { // if character is z
                result += 26;
                // get character numbers
        }// end if
}// end for
return (result % arraySize); // returns Hashed values
} // end hashFunc1()

Dani AI

Generated

Short version: the giant if-chain is unnecessary and fragile — as pointed out the letters are contiguous so they can be mapped arithmetically — but there are a couple of better, practical options that avoid the pitfalls of a naive sum-of-values.

A compact, reliable choice is to use Java's built-in string hash and reduce it into the table range. This is concise, well-tested, and preserves character order (unlike summing letter values which makes anagrams collide). For a case-insensitive index, convert to lower/upper and then reduce the hash into [0..arraySize-1] (use a floor-mod or mask to handle negative hashCode values).

int index = Math.floorMod(key.toLowerCase().hashCode(), arraySize);

For learning or when a custom hash is required, a simple multiply-add (polynomial/rolling) hash distributes values much better than a plain sum. Iterate over characters, map letters to a small value, multiply the running hash by a base (31 is common) and add the letter value, reducing modulo the table size as needed to keep values small and avoid overflow.

long h = 0;
for (char ch : key.toLowerCase().toCharArray()) {
    if (!Character.isLetter(ch)) continue;
    int v = ch - 'a' + 1; // maps a..z to 1..26
    h = (h * 31 + v) % arraySize;
}
int index = (int) h;

Notes and cautions tied to the thread: a result like "A -> 10" often comes from using Character.getNumericValue (it returns 10 for 'A'), not from subtracting the letter base. Recursion here gives no advantage over a simple loop and only adds stack overhead. Also handle non-letter characters explicitly (ignore or map to a value), use Character.toLowerCase()/isLetter for robustness, and test the hash for collisions with realistic inputs (small table sizes and simple sums collide a lot). Finally, choosing a good table size (often a prime) and using a tried-and-tested approach (String.hashCode or a rolling hash) will produce more uniform bucket distribution than the original many-ifs approach.

Recommended Answers

All 7 Replies

Replace the list of if statements with a statement that returns the value for the character.
Since the values of the chars are contiguous: 'b' = 'a' + 1 and you can do arithmetic with char variables,
consider these: 'b' - 'a' = 1 or 'z' - 'a' = 25

wouldn't you need the if statement though? It's meant for an entire string. Like if someone were to type Delaware it would turn that String into 11 since my hashtable is 29.

I feel there has to be a recursive way to do this

Do what? Seems like a loop is easier. By using arithmetic, lines 16 to 145 can be replaced by one statement.

I guess I don't understand. It has a loop. You think I should add another for it? I don't think I know how that would work because each time it makes a char an int it has to add with the previous values it found as well as obtain the value from the current char.
I could initially make chars the values 1,2,3,4..., but I don't know how that would work and still get the correct result. I just tried...

public int hashFunc (String key)
{
int result = 0;
String inputString = key.toString().toLowerCase(); 
// changes String to lowercase
char [] characters = inputString.toCharArray(); // makes String an Array
char a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10,k=11,l=12,m=13,n=14,o=15,p=16,
        q=17,r=18,s=19,t=20,u=21,v=22,w=23,x=24,y=25,z=26;
for (int index = 0; index < characters.length; index++) // loop
{
    result+=characters[index]; 
}// end for
return (result % arraySize); // returns Hashed values
} // end hashFunc1()

This is getting 10 for A it needs to be 1. I could subtract 1, but I want to understand why it is making A as a 10.

If 'A' is 1, then is 'B' 2 and 'C' 3 etc to 'Z' 26?

'B' - 'A' + 1 = 2
'C' - 'A' + 1 = 3
'Z' - 'A' + 1 = 26

Subtract 'A' and add 1

That's it for tonight. Back tomorrow.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.