字母频率统计 c语言,有关统计单词频率的算法c语言实现

从一文本中读取单词,统计其出现的频率,并按频率大小输出到另一文本中。这里的单词是分二种,一种是ASCII码大于0x20小于0X80字符,第 二种是小于0x20以及大于0x80的字符。这里我用的是哈希表,这样能很快查找读取的单词是否已经存在。排序我用的是二个循环,按理来说可以改进。

下面是我的算法。有些地方还需要改进。

#include

#include

#include

#define FOOL int

#define TURE 1

#define FALSE 0

#define MAXWORD 256

#define hashnum 1024

/*采用哈希表结点结构*/

typedef struct Hash{

int count;

char str[1]; /*不一定为1,而是动态分配*/

}Hash_table;

Hash_table hash_table[hashnum];

char buffer[256]; /*缓冲区大小,用来暂时存储单词*/

int tail_prob; /*缓冲区结束位指针 */

int Hcount = 0; /*用来计算有多少单词*/

/******************************************************************/

/** 初始化操作 **/

/** **/

void initial_buffer ()

{

for (tail_prob = 0; tail_prob < MAXWORD ;tail_prob++)

{

buffer[tail_prob++] = 0;

}

tail_prob = 0;

}

void initial_hashtable ()

{

unsigned int i;

i = 0;

while (i < hashnum)

{

hash_table[i].count = 0;

i++;

}

}

/******************************************************************/

/** 关于缓冲区的操作 **/

/** **/

/*把一个字符拷贝到缓存区中*/

void copytobuffer (char character)

{

if (tail_prob >= MAXWORD)

{

printf("Usag:this word is too long!");

exit (-1);

}

buffer[tail_prob++] = character;

}

/*清除缓冲区*/

void clear_buffer ()

{

while (tail_prob != 0)

{

buffer[--tail_prob] = 0;

}

}

/**************************************************************/

/** 找哈希表的关键字,这里使用的是把字符串的值相加再求与哈希表**/

/**长度的余 **/

unsigned int get_key (char *str)

{

unsigned result = 0;

do

{

result = result + (*str);

str++;

}while (*str != NULL);

result = result % hashnum;

return result;

}

/***************************************************************/

/**看哈希表中是否有对应的单词,有返回真 **/

/** **/

int find_match ()

{

int i;

char *str;

char *temp;

int len1; /*缓冲区中单词的长度*/

int len2; /*哈希表中单词的长度*/

int index;

str = buffer;

index = get_key (buffer);

temp = hash_table[index].str;

len1 = strlen (buffer);

len2 = strlen (temp);

while (hash_table[index].count)

{

if (len1 == len2) /*些比较len1和len2是否相等,如果不等再比较*/

{

for (i = 0;i

{

str++;

temp++;

}

if (i != len2)

{

index = (index + 1) % hashnum;

temp = hash_table[index].str;

str = buffer;

}

else //能找到

{

hash_table[index].count++;

return TRUE;

}

}

else

{

index = (index + 1) % hashnum;

temp = hash_table[index].str;

str = buffer;

}

}

}

/***************************************************************/

/** 根据缓冲区里面的字符生成哈希表 **/

/** **/

void addtoHash()

{

char str_temp[256];

char *str;

char *temp;

int len;

unsigned int index;

int i;

i=0;

str = str_temp;

strcpy (str,buffer);

index = get_key (str);

len = strlen(str);

temp = hash_table[index].str;

while (hash_table[index].count) /*找到没有被储存的结点*/

{

index = (index + 1) % hashnum;

}

hash_table[index].count++;

while (i < len) /*复制字符串*/

{

*temp++ = *str++;

i++;

}

}

/***************************************************************/

/** 排序后输出到out文件中 **/

/** **/

void Hash_sort(FILE *out)

{

int index;

unsigned int symbol; /*最小值*/

int num;

int len;

int i = 0;

index = 0;

/*排序输出到out文件中,共有Hcount个单词*/

while (i < Hcount)

{

/*找到第一个遇见的频率非零的结点*/

while (hash_table[index].count == 0)

{

index ++;

}

symbol = hash_table[index].count; /*充当最小值*/

num = index;

index++;

while (index < hashnum)

{

if (hash_table[index].count < symbol && hash_table[index].count)

{

symbol = hash_table[index].count;

num = index;

}

index ++;

}

/*找到了最小值*/

len = strlen (hash_table[num].str);

printf("%d ",hash_table[num].count);

printf("%s/n",hash_table[num].str);

fprintf(out,"%s,%d/n",hash_table[num].str,hash_table[num].count);

hash_table[num].count = 0;

i++;

index = 0;

}

}

/*****************************************************************

/*找文件in中单词出现的频率,存储其单词以及其频率,调用find_match*/

/*输入的字符小于等于Ox20或者大于0x80时说明不是数字或者字母。但是*/

/*也能组成一个单词 */

void find_frquence(FILE *in,FILE *out)

{

char character;

FOOL flag;

flag = 1; /*开关语句*/

initial_buffer();

initial_hashtable ();

/*当没有到文件结束时*/

character = fgetc (in);

do

{

if (character >0x20 && character < 0x80)

{

if (flag)

{

copytobuffer (character);

}

else /*新单词,且是字母和数字的组合*/

{

buffer[tail_prob] = '/0';/*表示结束*/

if(find_match ()) /*如果能够找到,相对应的频率加1*/

{

// Tprob->count++;

}

else /*不能找到,则生成一个新的结点加入孩子兄弟链表中*/

{

addtoHash ();

Hcount++;

}

clear_buffer ();

copytobuffer (character);

flag = !flag;

}

}

else

{

if (character <= 0x20 || character >= 0x80)

{

if (flag)

{

buffer[tail_prob] = '/0';

if (find_match ()) /*如果能够找到,则对应的频率加1,find_match实现频率加1*/

{

// Tprob->count++;

}

else /*不能找到,则到哈希表中*/

{

addtoHash ();

Hcount++;

}

clear_buffer (); /*清除缓冲区*/

copytobuffer (character);

flag = !flag;

}

else

{

copytobuffer (character);

}

}

}// if - else 结束

}while ((character = fgetc (in)) != EOF);

/*处理最后缓冲区所存储的单词*/

if(find_match())

{

// Tprob->count++;

}

else

{

addtoHash();

Hcount++;

}

/*排序并按从小到大输出到out文件中*/

Hash_sort(out);

}

/**************************************************************/

void main(int argc,char *argv[])

{

FILE *in;

FILE *out;

char temp_string1[256];

char temp_string2[256];

if(argc < 2)

{

printf ("Usag:please input the correct filename");

exit (-1);

}

if (strlen (argv[1]) >256 || strlen (argv[2]) > 256)

{

printf (" Usag:the filename is too long!");

exit (-1);

}

strcpy (temp_string1,argv[1]);

strcpy (temp_string2,argv[2]);

in = fopen (temp_string1,"rb");

out = fopen (temp_string2,"w");

/*找到各个单词,并且存储其频率,按频率顺序排列后输出到out中*/

find_frquence (in,out);

fclose (in);

fclose (out);

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值