题目概述:
给定一篇英语单词数少于50万的文章(.txt),要求统计每个单词出现的频数以及正篇文章单词数,并且要求将所得频数依据从大到小的顺序进行输出。(输出要求:单词名称 ===== 出现次数)
解题思想:
- 将.txt文件读入内存中;
- 设置一个world结构体用于存储单个单词,设置一个N结构体用于统计单词总个数,并在其中定义一个world结构体类型的指针,以便为后续操作提供便利;
- 将内存中的数据进行分割,将单词存入world结构体中;
- 统计单词出现的频数;
- 依据频数选取适当的排序算法进行排序,这里程序的采用的是希尔排序;
- 对结果进行输出
代码实现:
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;
}
程序输出: