Practice Assignment

(anagram.c)

Information

  1. Write a function that determines whether two words are anagrams. Two words are anagrams if they are both permutations of the same letters. For example, here are 3 anagrams:
      nicest  <--> insect
      senator <--> treason
      present <--> serpent
      
    The prototype for the function looks like this:
    int is_anagram(const char word1[], const char word2[], int size);
    
    If the two words are anagrams, you will return 1 (true). If they are not anagrams, you will return 0 (false). There are many ways to implement the solution, and I am going to explain 3 of them. All of them are different, so you should strive to implement all 3.

    Method #1 - Use an array to keep track of how many times each letter appears in each word. If the counts are the same, then they are anagrams. If the counts differ, they are not anagrams. The reason you want to use an array is because you don't want to have 26 separate variables (one for each letter). Instead, you'll have an array of 26 integers, one for each letter of the alphabet. Element 0 will correspond to the letter 'a', element 1 will correspond to the letter 'b', etc., with element 25 corresponding with the letter 'z'. (Remember, arrays are zero-based, so our 26 letters will be indexed from 0 to 25.) You will initialize all elements to the value 0 at the start.

    For example, the word pool and loop are anagrams. (loop is also pool spelled backwards, but that's another practice assignment!) The array for both words looks like this (the letters below the numbers are just for reference):

    0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 1 0 0 0 0 0 0 0 0 0 0
    a b c d e f g h i j k l m n o p q r s t u v w x y z
    
    That's because there is one letter 'l' (lowercase 'L') and it corresponds to slot 12 (index 11) in the array. There are two of the letter 'o', corresponding to slot 15 (index 14). Finally, there is one letter 'p', corresponding to slot 16 (index 15). If you create an array for both words, you can just check that the elements are the same in both. If they are the same, they are anagrams.

    A variation of this algorithm is to create just one array. You would increment each letter's count for the first word, and then decrement each letter's count for the second word. If all elements are now zero again, then they are anagrams. You can do it either way. The point is to practice with arrays.

    Approximate number of lines of code: 12.

    Method #2 - If you sort the letters in each word (from a to z) you can then just compare the two arrays, element by element. If they are the same, then they are anagrams. (Use the sort algorithm you implemented from a previous practice assignment.)

    Approximate number of lines of code: 12.

    Method #3 - This is similar to Method #2, except that instead of writing your own sort routine, you are going to use the qsort (quicksort) function from the C Standard Library (You need to include stdlib.h). This is the prototype for qsort:

    void qsort (void *base, size_t num, size_t size, int (*compare)(const void *,const void*));
    
    Yeah, it's ugly. Many of you will find that writing your own simple sort algorithm is actually easier and consumes less time than just understanding how to use qsort! However, it's very instructional to learn it. That's why I said I'm showing you 3 methods. Two require sorting. One of those requires you to write your own sort routine and the other requires you to learn how to use the one in the library. Hint: Google Is Your Friend™. Or, you can just read about it in the textbook.

    Approximate number of lines of code: 12.

    The name of the file should be anagram.c and the command to compile it will look like this:

    gcc -Werror -Wall -Wextra -ansi -pedantic -O2 -o anagram main.c anagram.c
    
    Files:

Notes

For those that would like an additional challenge:

  1. Handle words that are mixed uppercase and lowercase.
  2. Handle words that are of different lengths. This is relatively easy because, if they are different lengths, they can't be anagrams.
  3. Handle any length words. This will require dynamic memory allocation (malloc). DO NOT use a static array with an arbitrarily large size, e.g.:
    char letters[10000];
    
  4. And, of course, implement all 3 methods.