L-16 MCS 275 Wed 14 Feb 2001

Below are the listings for the programs we discussed in class.
/* L-16 MCS 275 Feb 2001 : divide and conquer continued */

#include <stdio.h>
#include <string.h>

#define  MAXLEN  80    /* maximum #characters in string */

int read_words (char *words[]);
/* reads words from standard input and stores them into 
   the array of strings and returns the number of strings read */
int rec_maxocc (int start, int end, char *names[], char *s);
/* Given an array of alphabetically sorted names (like in phonebook),
   this function searches for the string s that occurs most frequently
   in names between start and end in the array.
   When more than one name occurs with maximal frequency,
   the lexicographically least name is returned.
   The integer that is returned counts the frequency of that name. */
int itr_maxocc (int start, int end, char *names[], char *s);
/* iterative version of the routine above */

int main()
{
   char *words[MAXLEN];
   char name[MAXLEN];
   int i,n;

   n = read_words(words);
   printf("Read %d words : \n",n);
   for (i=0; i < n; i++)
      printf("  \"%s\"\n",words[i]);
   printf("Maximal occuring word with the iterative version...\n");
   i = itr_maxocc(0,n-1,words,name);
   printf("  Occurence of name \"%s\" is %d.\n", name, i);
   printf("Maximal occuring word with the recursive version...\n");
   i = rec_maxocc(0,n-1,words,name);
   printf("  Occurence of name \"%s\" is %d.\n", name, i);

   return 0;
}

int read_words (char *words[])

   int i;
   char word[MAXLEN];

   printf("Reading alphabetically sorted words.\n");
   for (i=0; ; i++)
   {
      printf("   Give a word (type 0 to stop) : ");
      scanf("%s", word);
      if (strcmp(word,"0") == 0)
         break;
      else
      {
         words[i] = (char*)calloc(MAXLEN, sizeof(char));
         strcpy(words[i],word);
         if (i > 0)
            if (strcmp(words[i-1],word) > 0)
               printf("WARNING : you destroyed the lexicographical order!\n");
      }
   }
   return i;
}

int itr_maxocc (int start, int end, char *names[], char *s)
{
   int i,cnt = 1;    /* cnt is frequency counter for current name */
   int max = start;  /* max is index to maximal occuring word */
   int maxcnt = 1;   /* maxcnt counts occurrency of names[max] */

   for (i = start+1; i <= end; i++)
      if (strcmp(names[i-1],names[i]) == 0)   /* still same name */
      {
         if (++cnt > maxcnt)
         {
             max = i;
             maxcnt = cnt;
         }
      }
      else                                   /* new name encountered */
         cnt = 1;
  
   strcpy(s,names[max]);
   return maxcnt;
}

int rec_maxocc (int start, int end, char *names[], char *s)
{
   int middle,leftcnt,rightcnt,middlecnt,i;
   char leftname[MAXLEN], rightname[MAXLEN], middlename[MAXLEN];

   if (start == end)
   {
      strcpy(s,names[start]); return 1;
   }
   else
   {
      middle = (start+end)/2;
      leftcnt = rec_maxocc(start,middle,names,leftname);
      rightcnt = rec_maxocc(middle+1,end,names,rightname);
      if (strcmp(leftname,rightname) == 0)
      {
         strcpy(s,leftname);
         return leftcnt+rightcnt;
      }
      else
      {
         i = middle-1;
         while ((i >= start) && strcmp(names[i],names[middle]) == 0) i--;
         middlecnt = middle - i;
         i = middle+1;
         while ((i <= end) && strcmp(names[i],names[middle]) == 0) i++;
         middlecnt = middlecnt + (i - middle) - 1;

         if (middlecnt > leftcnt)
         {
            if (middlecnt > rightcnt)
            {
               strcpy(s,names[middle]); return middlecnt;
            }
            else
            {
               strcpy(s,rightname); return rightcnt;
            }
         }
         else
         {
            if (rightcnt > leftcnt)
            {
               strcpy(s,rightname); return rightcnt; 
            }
            else
            {
               strcpy(s,leftname); return leftcnt;
            }
         }
      }
   }
}