**Problem : **
Give the best, average, and worst case efficiencies of both the brute-force
string search and Rabin-Karp string search.

M = length of pattern
N = length of text
Brute-force
Best =

*O*(*M*)
Average =

*O*(*MN*)
Worst =

*O*(*MN*)
Rabin-Karp
Best =

*O*(*M*)
Average =

*O*(*M* + *N*)
Worst =

*O*(*MN*)
**Problem : **
How does Rabin-Karp achieve an efficiency of *O*(*M* + *N*)?

The intial hash is

*O*(*N*). After that, each update is

*O*(1), and there
are

*O*(*N*) updates. Sometimes we need to do

*O*(*M*) work when the hash
values match, but we can ignore as a good hash function will not cause
many collisions. So

*O*(*M*) + *O*(1)**O*(*N*) = *O*(*M*) + *O*(*N*) = *O*(*M* + *N*).

**Problem : **
Using the hash() and hash_update() functions given in this section, give
an example of a pattern string and text string that will reduce Rabin-Karp
back to brute-force search, decreasing its efficiency back to *O*(*MN*).

Pattern string = "aabb"
Text string = "abababababababababaabb"
Because the hash function we're using only sums the letters, this pattern
will match the hash at almost every location in the text string as almost
every position has two a's and two b's.

**Problem : **
Challenge problem: Create a hash_update() function to go along with this
hash() function:

long hash_str(hash_table_t *hashtable, int hash_len, char *start)
{
long hval;
int i;
/* If the string passed in is NULL, return 0 */
if (start == NULL) return 0;
/* Multiply the old hash value by 257 and add the current character
* for as long as the string
*/
hval = 0L;
for(i=0; i < hash_len; i++) {
hval = ((257 * hval) + start[i]) % hashtable->size;
}
/* Return the hash value */
return hval;
}

Use the function prototype:

long hash_update(
long hval, /* old hash value */
char start, /* character to be removed */
char end, /* character to be added */
int hash_len, /* length of the string */
hash_table_t *hashtable ); /* the hash table */

long hash_update(
long hval,
char start,
char end,
int hash_len,
hash_table_t *hashtable )
{
/* Based on the length of the string, compute how many times the far
* left character (the one being removed) was multiplied by 257.
* NOTE: In a real implementation of this, you would want to do this as
* a precomputational step so that you wouldn't have to do it every time
* this function was called
*/
long mul_fac = 1;
for(i=0; i<hash_len; i++) {
mul_fac = (mul_fac * 257) % hashtable->size;
}
/* Determine the value of the oldest character after it was multiplied */
long oldest = (mul_fac * start) % hashtable->size;
/* Subtract it from the current hash value to remove it */
long oldest_removed = ((hval + hashtable->size) - oldest)
% hashtable->size;
/* Add in the new character as you would in the normal hash function */
hval = ((257 * oldest_removed) + end) % hashtable->size;
/* Return the new hash value */
return hval;
}

**Problem : **
Give a hash function and a hash update function that will always reduce
Rabin-Karp to *O*(*MN*) efficiency.

There are many. One example:

int hash(hash_table_t *hashtable, char *str)
{
return 220;
}
int hash_update(hash_table_t *hashtable, char *str)
{
return 220;
}

As every string hashes to the same number, Rabin-Karp will not save
anything over Brute-force. Of course, this is a terrible hash function
and you would never want to use it.