[ create a new paste ] login | about

Link: http://codepad.org/qS3Gh6kJ    [ raw code | fork ]

C, pasted on Nov 27:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Lib_node {
  void *data;
  struct Lib_node *left, *right;
};

void lib_init_list(struct Lib_node **root)
{
  *root = NULL;
}

void *lib_add_list(struct Lib_node **root, void *data, int (*cmp)(void *, void *))
{
  int c;
  struct Lib_node *node;

  if (*root == NULL) {
    if((node = malloc(sizeof(struct Lib_node))) == NULL) {
      fprintf(stderr, "cannot allocate enoutgh memory.\n");
      exit(-1);
    }
    node->data = data;
    node->left = node->right = NULL;
    *root = node;
    return data;
  }
  if ((c = (*cmp)(data, (*root)->data)) < 0) {
    return lib_add_list(&((*root)->left), data, cmp);
  } else if (c > 0) {
    return lib_add_list(&((*root)->right), data, cmp);
  } else {
    return (*root)->data;
  }
}

void *lib_delmin_list(struct Lib_node **root)
{
  void *data;
  struct Lib_node *p;

  if (*root == NULL)
    return NULL;
  if ((*root)->left != NULL)
    return lib_delmin_list(&((*root)->left));
  data = (*root)->data;
  p = *root;
  *root = p->right;
  free(p);
  return data;
}

struct wordpack {
  char *string;
  int wc;
  struct Lib_node *root;
};

struct appearpack {
  int line;
  int word;
};

int cmp0(struct appearpack *a, struct appearpack *b)
{
  return 1;
}

int cmp1(struct wordpack *a, struct wordpack *b)
{
  return strcmp(a->string, b->string);
}

int cmp2(struct wordpack *a, struct wordpack *b)
{
  if (a->wc > b->wc)
    return -1;
  else if (a->wc < b->wc)
    return 1;
  else
    return strcmp(a->string, b->string);
}

void regword(struct Lib_node **root, char *buff, int line, int word)
{
  char *s;
  struct wordpack *wp, *data;
  struct appearpack *ap;

  if ((s = malloc(strlen(buff) + 1)) == NULL) {
    fprintf(stderr, "cannot allocate an enough memory, aborted.\n");
    exit(-1);
  }
  strcpy(s, buff);
  if ((wp = malloc(sizeof(struct wordpack))) == NULL) {
    fprintf(stderr, "cannot allocate an enough memory, aborted.\n");
    exit(-1);
  }
  wp->string = s;
  wp->wc = 0;
  lib_init_list(&(wp->root));
  data = lib_add_list(root, wp, (int (*)(void *, void *))cmp1);  
  if (data != wp) {
    free(wp->string);
    free(wp);
  }
  data->wc++;  

  if ((ap = malloc(sizeof(struct appearpack))) == NULL) {
    fprintf(stderr, "cannot allocate an enough memory, aborted.\n");
    exit(-1);
  }
  ap->line = line;
  ap->word = word;
  lib_add_list(&(data->root), ap, (int (*)(void *, void *))cmp0);  
}

void output1(struct Lib_node **root1, struct Lib_node **root2)
{
  struct wordpack *wp;
  struct appearpack *ap;
  struct Lib_node *tmp_root;
  while ((wp = lib_delmin_list(root1)) != NULL) {
    printf("%s(%d) ", wp->string, wp->wc);
    lib_init_list(&tmp_root);
    while ((ap = lib_delmin_list(&(wp->root))) != NULL) {
      printf("L%d-%d ", ap->line, ap->word);
      lib_add_list(&tmp_root, ap, (int (*)(void *, void *))cmp0);
    }
    putchar('\n');
    wp->root = tmp_root;
    lib_add_list(root2, wp, (int (*)(void *, void *))cmp2);
  }
}

void output2(struct Lib_node **root)
{
  struct wordpack *wp;
  struct appearpack *ap;
  while ((wp = lib_delmin_list(root)) != NULL) {
    printf("%s(%d) ", wp->string, wp->wc);
    while ((ap = lib_delmin_list(&(wp->root))) != NULL) {
      printf("L%d-%d ", ap->line, ap->word);
      free(ap);
    }
    putchar('\n');
    free(wp->string);
    free(wp);
  }
}

void regline(struct Lib_node **root1, char *buff, int line)
{
  char *p, *q;
  int flag, word;

  word = flag = 0;
  p = q = buff;
  for(;;) {
    if (*p == '\0') {
      if (flag > 0) {
        regword(root1, q, line, word);
      }
      break;
    }
    if ((*p >= '0' && *p <= '9') || (*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || (*p == '_')) {
      if (flag == 0) {
        word++;
        flag = 1;
        q = p;
      }
    } else {
      if (flag > 0) {
        *p = '\0';
        regword(root1, q, line, word);
        flag = 0;
      }
    }
    p++;
  }
}

#define BUFFSIZE 1024 /* >= 2 */
char *getline(FILE *fp)
{
  static char inbuff[BUFFSIZE];
  char *outbuff_malloc, *tmpbuff;
  char *p, *q;
  int fEOL;
  if ((outbuff_malloc = malloc(1)) == NULL)
    return NULL;
  *outbuff_malloc = '\0';
  fEOL = 0;
  do {
    if ((q = fgets(inbuff, BUFFSIZE, fp)) == NULL)
      break;
    for (p = inbuff; *p != '\0'; p++)
      ;
    if (*(p - 1) == '\n') {
      *(p - 1) = '\0';
      fEOL = 1;
    }
    if ((tmpbuff = realloc(outbuff_malloc, strlen(outbuff_malloc) + strlen(inbuff) + 1)) ==NULL) {
      free(outbuff_malloc);
      return NULL;
    }
    strcat(tmpbuff, inbuff);
    outbuff_malloc = tmpbuff;
  } while (!fEOL);
  if (q == NULL) {
    free(outbuff_malloc);
    return NULL;
  }
  return outbuff_malloc;
}

int main(int argc, char *argv[])
{
  char *inputLine_malloc;
  FILE *fp;
  int line;
  struct Lib_node *root1, *root2;
  
  if (argc != 2) {
    fprintf(stderr, "usage: %s <file>\n", argv[0]);
    return -1;
  }
  if ((fp = fopen(argv[1], "r")) == NULL) {
    fprintf(stderr, "cannot open the file '%s'.\n", argv[1]);
    return -1;
  }
  
  lib_init_list(&root1);
  lib_init_list(&root2);
  line = 0;
  while ((inputLine_malloc = getline(fp)) != NULL) {
    line++;
    regline(&root1, inputLine_malloc, line);
    free(inputLine_malloc); /* NULL ok */
  }
  output1(&root1, &root2);
  putchar('\n');
  output2(&root2);
  fclose(fp);
  return 0;
}
/* end */


Create a new paste based on this one


Comments: