#99 Article 1062 Posted at 1995/12/21 13:08:28 by MEX (MAP5294) [SAHOU.4]

Subject: Re: プログラミング作法・お題4 /1052

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

#define KEYWORDMAX 200
#define KEYWORDLEN 32

static const char file_err_msg[] = "file read error.\n";
static char s[128];
static char keyword[KEYWORDMAX][128];
static int count[KEYWORDMAX][2];
static int fork;

static int cmp_str(const int *x, const int *y)
{
  return *x - *y;
}

int main(int argc, char *argv[])
{
  int i, j, k;
  FILE *src;

  if(argc != 2)
  {
    fprintf(stderr, "usage: %s [filename]\n", argv[0]);
    return 1;
  }

  for(i = 0; i < KEYWORDMAX; i++)
  {
    count[i][1] = i;
  }

  if(src = fopen(argv[1], "r"))
  {
    while(fscanf(src, "%127s", s) != EOF)
    {
      if(strlen(s) <= KEYWORDLEN)
      {
        for(i = 0; i < KEYWORDMAX; i++)
        {
          if(count[i][0])
          {
            if(!strcmp(s, &keyword[i][0]))
            {
              count[i][0]++;
              break;
            }
          }
        }
        if(i == KEYWORDMAX)
        {
          j = INT_MAX;
          for(i = 0; i < KEYWORDMAX; i++)
          {
            if(count[fork][0] < j) j = count[(k = fork)][0];
            if(++fork == KEYWORDMAX) fork = 0;
          }
          if(++fork == KEYWORDMAX) fork = 0;
          count[k][0] = 1;
          strcpy(&keyword[k][0], s);
        }
      }
    }
    if(ferror(src))
    {
      fclose(src);
      fputs(file_err_msg, stderr);
      return 1;
    }
    if(fclose(src))
    {
      fputs(file_err_msg, stderr);
      return 1;
    }
  }
  else
  {
    fputs(file_err_msg, stderr);
    return 1;
  }

  qsort(count, KEYWORDMAX, sizeof(int) * 2, cmp_str);

  for(i = KEYWORDMAX - 1; i >= 0; i--)
  {
    if(count[i][0])
    {
      printf("%5d: %s\n", count[i][0], &keyword[count[i][1]][0]);
    }
  }
  return 0;
}

USAGE----
Cです。実行方法は program [filename]
BUGS----
キーワードの長さは32文字まで、キーワードの種類は最大200まで。
種類がそれより多くなると、近似的な結果しか得られません。
特にログファイルなど、キーワードの種類が無数にあるものの場合
ファイルの先頭方向に密集したキーワードが優先してしまいます。

MAP5294 MEX