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

typedef struct {
  char *s ;
  int n ;
} str_num_pair ;

typedef struct {
  str_num_pair **array ;
  int arraylen ;
} converter_t ;

int ptr_strcmp(str_num_pair **a, str_num_pair **b)
{
  return strcmp((*a)->s, (*b)->s) ;
}

void *construct_s2i_converter(int arraylen, char **array)
{
  str_num_pair **sort_array ;
  converter_t *converter ;
  int i ;

  sort_array = (str_num_pair **)malloc(sizeof(str_num_pair *) * arraylen) ;
  for (i=0 ; i < arraylen ; i++) {
    sort_array[i] = (str_num_pair *)malloc(sizeof(str_num_pair)) ;
    sort_array[i]->s = array[i] ;
    sort_array[i]->n = i ;
  }

  qsort(sort_array, arraylen, sizeof(str_num_pair *), 
	(int (*)(const void *, const void *))ptr_strcmp) ;

  converter = (converter_t *)malloc(sizeof(converter)) ;
  converter->array = sort_array ;
  converter->arraylen = arraylen ;

  return converter ;
}

int str_to_index(void *converter, char *str)
{
  int retval ;
  str_num_pair **sort_array ;
  int len, max, min, item, dir ;

  retval = -1 ;

  sort_array = ((converter_t *)converter)->array ;
  len = ((converter_t *)converter)->arraylen ;

  min = 0 ;
  max = len-1 ;
  while (retval == -1 && max >= min) {
    item = (int)((max+min)/2) ;
    dir = strcmp(str, sort_array[item]->s) ;
    if (dir == 0)
      retval = sort_array[item]->n ;
    else if (dir < 0) 
      max = item-1 ;
    else
      min = item+1 ;
  }

  return retval ;
}
