L-14 MCS 275 Fri 9 Feb 2001

Below are the listings for the programs we discussed in class.
/* L-14 MCS 275 Fri 9 Feb 2001 : binary search */

#include <stdio.h>
#include <string.h>
#include <stdlib.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 search (int start, int end, char *words[], const char s[]);
/* Given an array of alphabetically sorted words,
   this function searches for the string s in the range
   between start and end in the array.
   If the string s matches the words[i], then i is returned.
   Otherwise -1 is returned. */
int lookup (int n, char *words[], const char s[]);
/* iterative version of the search above */

int main()
{
   char *words[MAXLEN];
   char searchfor[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]);
   for ( ; ; )
   {
      printf("Give a string (type 0 to stop) : ");
      scanf("%s",searchfor);
      if (strcmp(searchfor,"0") == 0) break;
      i = search(0,n-1,words,searchfor);
      printf("Your string \"%s\"",searchfor);
      if (i == -1)
         printf(" does not occur among the given words.\n");
      else
         printf(" matches given word at position %d.\n", i);
      printf("Searching with the iterative version...\n");
      i = lookup(n,words,searchfor);
      printf("Your string \"%s\"",searchfor);
      if (i == -1)
         printf(" does not occur among the given words.\n");
      else
         printf(" matches given word at position %d.\n", 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 search (int start, int end, char *words[], const char s[])
{
   int middle,cmpres;

   if (start > end)                        /* empty range */
      return (-1);
   else if (start == end)                  /* only one word in range */
      if (strcmp(words[start],s) == 0)
         return start;
      else
         return (-1);
   else
   {
      middle = (start + end)/2;            /* bisect the range */
      cmpres = strcmp(words[middle],s);
      if (cmpres == 0)                     /* middle word matches s */
         return middle;
      else if (cmpres > 0)                 /* middle word larger than s */
         return search(start,middle-1,words,s);
      else                                 /* middle word less than s */
         return search(middle+1,end,words,s);
   }
}

int lookup (int n, char *words[], const char s[])
{
   int start,end,middle,cmpres;

   start = 0;
   end = n-1;
   while (start <= end)
   {
      middle = (start+end)/2; 
      cmpres = strcmp(words[middle],s);
      if (cmpres == 0)
         return middle;
      else if (cmpres > 0)
         end = middle-1;
      else
         start = middle+1;
   }
   return (-1);
}