文章单词频数统计-----(C语言版)

题目概述:

给定一篇英语单词数少于50万的文章(.txt),要求统计每个单词出现的频数以及正篇文章单词数,并且要求将所得频数依据从大到小的顺序进行输出。(输出要求:单词名称 ===== 出现次数)

解题思想:

  1. 将.txt文件读入内存中;
  2. 设置一个world结构体用于存储单个单词,设置一个N结构体用于统计单词总个数,并在其中定义一个world结构体类型的指针,以便为后续操作提供便利;
  3. 将内存中的数据进行分割,将单词存入world结构体中;
  4. 统计单词出现的频数;
  5. 依据频数选取适当的排序算法进行排序,这里程序的采用的是希尔排序;
  6. 对结果进行输出

 代码实现:

test.h文件:

#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#define MAX 500000                     //开辟最大Word类型空间个数
#define MAX_SIZE 40                    //单词的最大长度
typedef struct Word
{
	char arr[MAX_SIZE];
	int count;                         //当前单词的个数
}Word;                                 //储存每个单词
typedef struct Num
{
	Word *brr;                         //指向结构体的指针
	int length;                        //总单词数量
}N;  

char* Read_In();                       //读取文件

N Deal_String(N t,char *str);          //处理字符串

void Deal_Struct(N *pnum ,char *str);  //Word类型变量赋值     

N Get_Factor(N t);                     //获取频数

void Shell(N t,int len,int gap);

N Shell_Sort(N t);                     //希尔排序/Shellpaixu

void Show(N t);                        //输出

test.cpp文件:

#include "test.h"


char* Read_In()                                       //将文件内容读入内存
{
	const  char *path = "E:\\1.txt";
	FILE *pr = fopen(path,"rb");                      //打开文件
	assert(pr !=NULL);                                //断言
	fseek(pr,0,SEEK_END);                             //指向文件末尾
	long lSize = ftell(pr);                           //求整个文件字节数
	fseek(pr,0,SEEK_SET);                             //指向文件开头
	char *str = (char*)malloc(lSize+1);               //开辟内存空间,存取文件 
	assert(str != NULL);                              //断言
	fread(str,sizeof(char),lSize,pr);                 //读取文件
	*(str+lSize) = '\0';                              //手动置'\0'
	fclose(pr);                                       //关闭文件
	return str; 
}


void Deal_Struct(N *pnum ,char *str)               
{
	assert(pnum != NULL && str != NULL);
	strcpy(pnum->brr[pnum->length].arr,str);     //给Word类型的数组拷贝值   
	pnum->brr[pnum->length].count = 1;           //count置1  

}


N Deal_String(N t,char *str)               //处理字符串,将文件中的单词存在结构体中         
{
	assert(str != NULL);                   //断言
	char arr[MAX_SIZE]={};                 //定义一个数组暂存当前单词
	int flag = 0;                          //设置标志位
	int i = 0; 
	while(*str != '\0')
	{
	  if((isalpha(*str))||(*str == '\''))  //如果是单词或者是'\'' 执行
		{
		  arr[i++] = *str;                 //将单词字母陆续存入数组arr[]
		  flag = 1;                        //标志位置一
		}
	  else if(flag)                        //只有符合第一个条件,才会进入此if语句   
	   {
		  i = 0;                           //数组下标置0
		  flag = 0;                        //标志位置零
	      Deal_Struct(&t,arr);             //赋值操作
		  memset(arr,0,sizeof(arr));       //数组置'\0'
	      t.length++;                      //单词总个数加一
	   }
	      str++;                           //字符位置加一
	}
	printf("单词共个数为====%ld\n",t.length);
	return t;
}


N Get_Factor(N t)                         
{
	for(Word* p = t.brr;p < t.brr + t.length - 1;p++)
	{
		for(Word* q = p + 1;q < t.brr + t.length && p->count != 0;q++)
		{
			if(strcmp(p->arr,q->arr)==0)
			{	
				p->count++;
				q->count = 0;    //将count置为0,下次遇到是不重新计数
			}
		}		
	}
	return t;
}

void Shell(N t,int len,int gap)
 {
	 for(int i = 0;i < t.length;i++)
	 {
		 Word temp = t.brr[i] ;
		 int j = 0;
		 for(j = i-gap;j >= 0;j-=gap)
		 {
			 if(t.brr[j].count < temp.count)
			 {
				 t.brr[j+gap] = t.brr[j];
			 }
			 else
			 {
				 break;
			 }
		 }
		 t.brr[j+gap] = temp;
	 }
 }


 N Shell_Sort(N t)              
{
	int drr[] = {97,87,71,57,23,17,13,3,1};
	int lend = sizeof(drr)/sizeof(drr[0]);
	for(int i = 0;i < lend;i++)
	{
		Shell(t,t.length,drr[i]);
	}
	return t;
}


 N Insert_Sort(N t)
 {
	 for(int i = 0;i < t.length;i++)
	 {
		 Word temp = t.brr[i];
		 int j = 0;
		 for(j = i-1;j >=0;j--)
		 {
			 if(t.brr[j].count < temp.count)
			 {
				 t.brr[j+1] = t.brr[j];
			 }
			 else
			 {
				 break;
			 }
		 }
		 t.brr[j+1] = temp;
	 }
	 return t;
 }

void Show(N t)
{
	for(Word *k = t.brr;k < t.brr+t.length;k++)
	{
		if(k->count != 0)
		{
			printf("%15s ===== %d\n",k->arr,k->count);
		}
	}
}	

main()函数:

#include "test.h"

int main()
{
	N s1;     
	s1.length = 0;                               //初始化
	s1.brr = (Word*)malloc(MAX*sizeof(Word));    //开辟内存空间
	assert(s1.brr != NULL);                      //断言
	char *str = Read_In();
	N num = Deal_String(s1,str);
	N num2 = Get_Factor(num);
	N num3 = Shell_Sort(num2);
	Show(num3);
	free(str);                                   //释放内存
	free(s1.brr);                                //释放内存
	return 0;
}

程序输出:

  • 11
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值