#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#pragma warning(disable:4996)
#define MAX 30//取决于最长单词长度
#define SIZE 20000//取决于不重复单词个数
typedef struct word {
char words[MAX];
int count;
}word;//存放单词及其频数
int first(word* w[], char* single, int n);
void putin(char* str, word* w[], int i, int n);
int handle(FILE* fp, word* w[]);
void Sort(word* w[], int n);
void Swap(word* w1, word* w2);
void show(word* w[], int n);
int main(int argc, char* argv[])
{
int n, i;//n代表不重复单词的总数
FILE* fp;
word* w[SIZE];
if (argc == 1)
{
printf("No filed name entered, strike any key to exit.\n");
getchar();
exit(0);
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
printf("Cannot open %s.\n", argv[1]);
getchar();
exit(1);
}
n = handle(fp, w);
Sort(w, n);
show(w, n);
fclose(fp);
for (i = 0; i < n; i++)
free(w[i]);
return 0;
}
int first(word* w[], char* single, int n)
//判断单词是否第一次出现
//返回i代表重复单词在结构体数组中的位置,返回-1代表第一次出现
{
int i;
if (n == 0)
return -1;
else
for (i = 0; i < n; i++)
if (strcmp(w[i]->words, single) == 0)//strcmp函数用于判断两个字符串是否相等
return i;
return -1;
}
void putin(char* str, word* w[], int i, int n)
//将单词存放结构体中
//首次出现的单词存放进新的数组,重复出现的使对应频数+1
//n代表不重复单词的总数
{
int t = 0;
if (i == -1)//不重复单词
{
while (str[t] != '\0')
{
w[n]->words[t] = str[t];
t++;
}
w[n]->words[t] = '\0';
w[n]->count = 1;
}
else//重复单词
w[i]->count++;
}
int handle(FILE* fp, word* w[])
//将文件中的字符处理成单词(大写将全部转换成小写
{
int i = 0, n = 0;
char ch, bh = 0;//bh用于处理单词中含有单引号的情况
char single[MAX] = { 0 };
while ((ch = fgetc(fp)) != EOF)
{
if (!isalpha(ch))//遇到下一个非字母字符后,重置bh
bh = 0;
if (isalpha(ch) && bh != 0)//当bh不为零且ch是字母时,说明当前字符处于单引号之后,跳过本次循环
continue;
if (!isalpha(ch) && ch != '-')//遇到非字母字符且该字符不为连字符时跳过本次循环
continue;
i = 0;
while (isalpha(ch) || ch == '-')
{
if (ch >= 'A' && ch <= 'Z')//将大写字母全部转换成小写字母
ch += 32;
single[i++] = ch;
ch = fgetc(fp);
}
single[i] = '\0';//手动添加'\0'
if (ch == '\'')//处理单引号后面的字母序列
bh = ch;
w[n] = (word*)malloc(sizeof(word));
if (first(w, single, n) == -1)//first函数用于判断single是否第一次出现
n++;//n代表不重复的单词的总数
putin(single, w, first(w, single, n), n - 1);//putin函数用于将该字符串的相关数据保存进w中
}
return n;
}
void Swap(word* w1, word* w2)
//交换两个结构体
{
word w;
strcpy(w.words, w1->words);
w.count = w1->count;
strcpy(w1->words, w2->words);
w1->count = w2->count;
strcpy(w2->words, w.words);
w2->count = w.count;
}
void Sort(word* w[], int n)
//将单词按频数进行排序
//频数相同的按字典序排序
{
int i, j, f;//f作为标志
for (i = 0; i < n - 1; i++)
{
f = 1;
for (j = 0; j < n - 1; j++)
{
if (w[j]->count < w[j + 1]->count)//比较频数
{
Swap(w[j], w[j + 1]);
f = 0;
}
else if (w[j]->count == w[j + 1]->count)//频数相同则按字典序排序
{
if (strcmp(w[j]->words, w[j + 1]->words) > 0)//比较字符串大小(字典序),大于0说明前者比后者大
Swap(w[j], w[j + 1]);
f = 0;
}
}
if (f == 1)//f==1说明上述排序已经完成,可提前终止
break;
}
}
void show(word* w[], int n)
//输出
{
int i;
for (i = 0; i < n; i++)
fprintf(stdout, "%d:%s\n", w[i]->count, w[i]->words);
printf("打印成功!");
}
500个英文单词统计词频,但是txt文本只能放大概10个单词才能运行,多了会出现这样的错误
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
1条回答 默认 最新
- fuill 2022-01-07 12:49关注
试试这样,D盘建一个文件text.txt,用文件目录的方式打开文件
测试可以用的#include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #pragma warning(disable:4996) #define MAX 30//取决于最长单词长度 #define SIZE 20000//取决于不重复单词个数 typedef struct word { char words[MAX]; int count; } word; //存放单词及其频数 int first(word* w[], char* single, int n); void putin(char* str, word* w[], int i, int n); int handle(FILE* fp, word* w[]); void Sort(word* w[], int n); void Swap(word* w1, word* w2); void show(word* w[], int n); int main() { int n, i;//n代表不重复单词的总数 FILE* fp; word* w[SIZE]; /*if (argc == 1) { printf("No filed name entered, strike any key to exit.\n"); getchar(); exit(0); }*/ if ((fp = fopen("D:\\text.txt", "r")) == NULL) { printf("Cannot open \n"); getchar(); exit(1); } n = handle(fp, w); Sort(w, n); show(w, n); fclose(fp); for (i = 0; i < n; i++) free(w[i]); return 0; } int first(word* w[], char* single, int n) //判断单词是否第一次出现 //返回i代表重复单词在结构体数组中的位置,返回-1代表第一次出现 { int i; if (n == 0) return -1; else for (i = 0; i < n; i++) if (strcmp(w[i]->words, single) == 0)//strcmp函数用于判断两个字符串是否相等 return i; return -1; } void putin(char* str, word* w[], int i, int n) //将单词存放结构体中 //首次出现的单词存放进新的数组,重复出现的使对应频数+1 //n代表不重复单词的总数 { int t = 0; if (i == -1)//不重复单词 { while (str[t] != '\0') { w[n]->words[t] = str[t]; t++; } w[n]->words[t] = '\0'; w[n]->count = 1; } else//重复单词 w[i]->count++; } int handle(FILE* fp, word* w[]) //将文件中的字符处理成单词(大写将全部转换成小写 { int i = 0, n = 0; char ch, bh = 0;//bh用于处理单词中含有单引号的情况 char single[MAX] = { 0 }; while ((ch = fgetc(fp)) != EOF) { if (!isalpha(ch))//遇到下一个非字母字符后,重置bh bh = 0; if (isalpha(ch) && bh != 0)//当bh不为零且ch是字母时,说明当前字符处于单引号之后,跳过本次循环 continue; if (!isalpha(ch) && ch != '-')//遇到非字母字符且该字符不为连字符时跳过本次循环 continue; i = 0; while (isalpha(ch) || ch == '-') { if (ch >= 'A' && ch <= 'Z')//将大写字母全部转换成小写字母 ch += 32; single[i++] = ch; ch = fgetc(fp); } single[i] = '\0';//手动添加'\0' if (ch == '\'')//处理单引号后面的字母序列 bh = ch; w[n] = (word*)malloc(sizeof(word)); if (first(w, single, n) == -1)//first函数用于判断single是否第一次出现 n++;//n代表不重复的单词的总数 putin(single, w, first(w, single, n), n - 1);//putin函数用于将该字符串的相关数据保存进w中 } return n; } void Swap(word* w1, word* w2) //交换两个结构体 { word w; strcpy(w.words, w1->words); w.count = w1->count; strcpy(w1->words, w2->words); w1->count = w2->count; strcpy(w2->words, w.words); w2->count = w.count; } void Sort(word* w[], int n) //将单词按频数进行排序 //频数相同的按字典序排序 { int i, j, f;//f作为标志 for (i = 0; i < n - 1; i++) { f = 1; for (j = 0; j < n - 1; j++) { if (w[j]->count < w[j + 1]->count)//比较频数 { Swap(w[j], w[j + 1]); f = 0; } else if (w[j]->count == w[j + 1]->count)//频数相同则按字典序排序 { if (strcmp(w[j]->words, w[j + 1]->words) > 0)//比较字符串大小(字典序),大于0说明前者比后者大 Swap(w[j], w[j + 1]); f = 0; } } if (f == 1)//f==1说明上述排序已经完成,可提前终止 break; } } void show(word* w[], int n) //输出 { int i; for (i = 0; i < n; i++) fprintf(stdout, "%d:%s\n", w[i]->count, w[i]->words); printf("打印成功!"); }
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥15 用verilog实现tanh函数和softplus函数
- ¥15 求京东批量付款能替代天诚
- ¥15 slaris 系统断电后,重新开机后一直自动重启
- ¥15 51寻迹小车定点寻迹
- ¥15 谁能帮我看看这拒稿理由啥意思啊阿啊
- ¥15 关于vue2中methods使用call修改this指向的问题
- ¥15 idea自动补全键位冲突
- ¥15 请教一下写代码,代码好难
- ¥15 iis10中如何阻止别人网站重定向到我的网站
- ¥15 滑块验证码移动速度不一致问题