I am working on a java project for school. I am trying to think more into a professional mindset rather than a student. The project I am working on is about hashing. The rest of the project looks really good, but this part makes me wonder if a professional programmer would do this. From what I understand is Java is mostly understanding, implementing, and manipulating algorithms. To me this seems like I just used a simple algorithm to obtain the desired result. I just want to see if it seems efficient and professional. So in your professional opinion does this look professional and efficient?

/**
 * 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 index = 0; index < characters.length; index++) // loop
{
    result+=characters[index]-9;
//adds result and subtracts 9 to make unicode into values A,B,C...=1,2,3...
}// end for
return (result % arraySize); // returns Hashed values
} // end hashFunc()

The pseudocode logic for this is

set result to zero
change Strings to lower-case
make the string an array of chars
loop through the string
obtain the unicode value of current character and subtract 9
add this result to other character results in the string(+=)
(the unicode of a=10 subtract 9 and it converts the unicode into the desired numberset.)
return result total mod ArraySize(29 in this project)

Thanks for your help!

Comments:
The code is poorly formatted
If key is a String, why do this: key.toString() use key directly
What does this mean: subtracts 9 to make unicode into values A,B,C...=1,2,3...
'A' - 9 = 56 not 1

Edited 4 Years Ago by NormR1

From what I understand is Java is mostly understanding, implementing, and manipulating algorithms.

That's universal, it's not unique to Java.

To me this seems like I just used a simple algorithm to obtain the desired result.

In my opinion, a good professional would start with the simplest algorithm that meets requirements and only make it more complex as necessary. While it might seem inefficient, for example, I'll often use a very simple linear search on collections that are unlikely to be large enough to warrant something "faster".

So in your professional opinion does this look professional and efficient?

Well, it's poorly formatted, so that makes it unprofessional. It's not inefficient, but it is one of the worst possible hashing methods[1], so I'd say it's an unprofessional function because it fails to meet the requirements of your typical hash function: fast and minimal collisions.

[1] See additive hashing on this website.

I was told it was unicode. I looked it up and realized how stupid that was for me to say that. The value I am getting when I make the key "a" is 10. for "b" I get 11. For "C" I get 12...Subtracting 9 gets the desired result. I would like to understand why it does this. The format though is because the code link wouldn't work well for me. I don't know if it is just this version of chrome. It doesn't look that way on the project. That is poor formatting, but I just didn't take the proper time to space each line that needed it with a few more spaces. I got rid of the .toString(). I thought that was wrong to use because it was in a String as it is. Do you know why the output is 10 for "a"(without subtracting 9)? If you know of a way that will show the math or logic that would help. Yes, it does get the desired result, but I want to know why it is that way. I was told it is obtaining the unicode value, which you and the unicode chart told me is wrong, but it is pulling a value from that char and from each char it reads. It is obtaining values based off of what the char is.

    /**
     * Changes String to int
     * @param key: String
     * @return (result % arraySize): int
     */
    public int hashFunc (String key)
   {
        int result = 0;
        String inputString = key.toLowerCase(); // changes String to lowercase
        char [] characters = inputString.toCharArray(); // makes String an Array

        for (int index = 0; index < characters.length; index++) // loop
        {
            result+=characters[index]-9;
            //adds result and subtracts 9 to make values A,B,C...=1,2,3...
        }// end for
        return (result % arraySize); // returns Hashed values
   } // end hashFunc()

I had my hashing a different way that avoided so many collisions(which are taken care of by linked lists), but my teacher wants it to have values a=1 b=2 c=3...etc. I think he wants it that way due to it being easier to grade. He's very big on making things look professional, but won't take off if it's not perfect. I actually am looking into programming some apps for Android and the upcoming Leap Motion for PC and I can use Java for it so I want my coding to look really good. I fixed the spacing on here(above) like I said it's not like that on my program.

wants it to have values a=1 b=2 c=3.

To make f('a') = 1 do this: subtract 'a' and add 1
'a' - 'a' + 1 = 1
'b' - 'a' + 1 = 2
etc

Are you confusing the hexidecimal values of hex digits with the values of chars?
The hex digit A represents the int value 10, B is 11 etc through F = 15

The int value of 'A' is 65

Edited 4 Years Ago by NormR1

Ah I must be confusing those values, but it works beyond F. It knows Z is 35 which with my program would make it 6(because the arraySize is 29) but then subtract the 9 and you get 26 which is the number I need it to be.
So I need to make a function f('a')=1. subtracting a(which is 1) then adding (1) seems counterintuitive for this. Maybe I am not understanding that part. Shouldn't it be a=0+1,b='a'+1, c='b'+1,...(something like this I could do recursively or through a loop.)

From what my teacher has explained the entire point of recursion is not to make it more professional or faster for the computer. Recursion is very inefficient for the computer, but in terms of programmer time it is efficient. I think it would be wiser for me to consider this method professional and efficient because it provides the desired result, doesn't use the resources that recursion does, and didn't take a large amount of programmer time(on top of that I would make a more efficient hash function that would probably produce a random hash rather than this)

If a=10, b=11, c=12,...,x=33, y=34, z=35 what code is that? HEX only has A-F, but not all the way to Z. I can't figure out why it does that. Even though it works I want to understand it to document it a little better.

Recursion is very inefficient for the computer, but in terms of programmer time it is efficient.

It depends. Pretty much any compiler these days will perform tail recursion optimization such that if you only recurse once and it's the last thing you do, the recursion will be converted to iteration internally. So this would likely be just as efficient as a non-recursive implementation because it uses tail recursion:

int factorial(int n)
{
    if (n <= 1)
        return 1;

    return n * factorial(n - 1);
}

For more complex recursive algorithms that cannot fully use that optimization, the overhead of stack frames may not be as significant as your teacher is implying. When recursion is used properly (binary search is a good example), the depth of recursive calls is kept to a minimum. The overhead is also far less significant than it used to be, such that recursion is often efficient enough except for the most persnickety of realtime applications.

a(which is 1)

Can you explain what you mean here? Are you talking about the char value: 'a' or what?
Or are you talking about an int variable named a: int a = 1;
Your discussions are very ambiguous and impossible to follow unless you define the terms you are using.

To make f('a') = 1 do this: subtract 'a' and add 1
'a' - 'a' + 1 = 1 <----This makes 'a'=1 right?
'b' - 'a' + 1 = 2 <----If 'b' currently has no value, but you are assigning it a value of 'b'-'a'+ 1 = 2 how does that work? It seems essentially you could remove the 'b'-'a'+1 and just say 'b'=2. No disrespect to you because I'm positive you are a much better programmer than I am and I don't understand that completely. I am just saying it isn't explained properly. I have three other people who have looked at what you wrote and said that doesn't make since. I don't think you're explaining that concept as well as it makes since in your head. I'm not saying it doesn't work. I'm saying I don't understand and it doesn't look like you have explained it too well.
etc

I am referring to what you wrote. See my comment above

So this would likely be just as efficient as a non-recursive implementation because it uses tail recursion

Not sure if that was intended but the function you posted isn't tail recursive because the state information has to be saved on the stack frame to carry out the multiplication. :)

A tail recursive function would be something like:

int factorial1(int n, int accumulator) {
    if (n == 0)
        return accumulator;
    return factorial1(n - 1, n * accumulator);
}

int factorial(int n) {
    return factorial1(n, 1);
}

On a related note, JVM unfortunately doesn't do tail call optimizations so you'll either have to:

  • Convert code to use a non-resursive solution
  • Use an explicit stack data structure and modify your recursive code a bit
  • Use a JVM language like Scala which detects tail recursion and performs the necessary optimization before writing out the JVM bytecode

Edited 4 Years Ago by ~s.o.s~

This question has already been answered. Start a new discussion instead.