如何統計一本英文書(比如簡愛)中出現次數最多的前1000個單詞
如何統計一本書中出現最多的前1000個單詞,其實只要處理好新單詞的儲存,已經出現單詞個數的統計,和根據出現次數的排序,就基本完成了這個專案。
思路:1、從檔案中依次讀取一個個字元,如果是字母字元就放到一個字元陣列中,當讀取的字元是空格或者標點符號時,則已經讀取的字串視為一個單詞,將其儲存起來。 2、儲存的話,我們可以定義一個新的結構體資料型別,裡面就包含所要儲存的單詞和這個單詞已經出現的次數。用新的結構體資料型別來動態建立一個數組來儲存單詞。 3、判斷讀取的單詞是否已經儲存過,有則把它的數量+1,沒有就新增新的單詞,新增新單詞之後,就用realloc函式擴大陣列的容量。 4、列印陣列的前1000個元素。
typedef struct Find_word //定義單詞結構體
{
char word[26];
int number;
}fin;
char word[26]用來儲存單詞,int number用來儲存單詞的個數。
void Find() { fin *arr=(fin *)calloc(1,sizeof(fin)); char brr[26]="0"; fin *crr; int i=0; int j=0; char p='0'; FILE *fp=fopen("2.txt","r"); while(!feof(fp)) { p=fgetc(fp); if(Myisalpha(&p)) { if(isupper(p)) { p=tolower(p); } brr[i]=p; brr[i+1]='\0'; i++; } else { if(Find_index (arr,brr)==0) { crr=(fin *)realloc(arr,(j+2)*sizeof(fin)); //每次需要記錄新單詞時新增兩個fin格子 arr = crr; for(int i_a=j+1;i_a<j+2;i_a++) //將新新增的fin格子的number置為0 { arr[i_a].number=0; } strcpy(arr[j].word,brr); arr[j].number += 1; i = 0; j++; } else { arr[Find_index(arr,brr)].number++; i = 0; } } } Sort(arr); Show(arr); fclose(fp); free(arr); }
bool Myisalpha(char *p); //是一個判斷是否為字母的函式
bool Myisalpha(char *p) //判斷字元是否為字母 { char arr[54]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'"; for(int i=0;arr[i]!='\0';i++) { if(*p==arr[i]) { return true; } } return false; }
int Find_index(fin *arr,char *brr); //找出已記錄過單詞的下標,通過這個下標將這個單詞的出現次數+1
int Find_index(fin *arr,char *brr) //找出已記錄單詞的下標
{
for(int i=0;arr[i].number!=0;i++)
{
if(strcmp(arr[i].word,brr)==0)
{
return i;
}
}
return 0;
}
void Sort(fin *arr); //按出現頻率排序
void Sort(fin *arr) //按出現頻率排序
{
int tmp=0;
char stmp[26]="0";
for(int i=0;arr[i].number != 0;i++)
{
for(int j=i+1;j>0;j--)
{
if(arr[j].number>arr[j-1].number)
{
tmp=arr[j].number;
strcpy(stmp,arr[j].word);
arr[j].number=arr[j-1].number;
strcpy(arr[j].word,arr[j-1].word);
arr[j-1].number=tmp;
strcpy(arr[j-1].word,stmp);
}
}
}
}
void Show(fin *arr) ; //列印前1000個單詞
void Show(fin *arr) //列印前1000個單詞
{
for(int i=0;i<1000;i++)
{
printf("%d, %s, %d",i+1,arr[i].word,arr[i].number);
printf("\n");
}
printf("\n");
}
你也可以以單詞表的形式排序,打印出來,專案完整程式碼如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
typedef struct Find_word //定義單詞結構體
{
char word[26];
int number;
}fin;
void Show1(fin *arr); //列印全部單詞
void Show(fin *arr); //列印前1000個單詞
int Find_index(fin *arr,char *brr); //找出已記錄單詞的下標
void Sort(fin *arr); //按出現頻率排序
void Sort1(fin *arr); //按單詞表排序
bool Myisalpha(char *p); //判斷是否為字母
void Show1(fin *arr) //列印全部單詞
{
for(int i=0;arr[i].number!=0;i++)
{
printf("%d, %s, %d",i,arr[i].word,arr[i].number);
printf("\n");
}
printf("\n");
}
void Show(fin *arr) //列印前1000個單詞
{
for(int i=0;i<1000;i++)
{
printf("%d, %s, %d",i+1,arr[i].word,arr[i].number);
printf("\n");
}
printf("\n");
}
int Find_index(fin *arr,char *brr) //找出已記錄單詞的下標
{
for(int i=0;arr[i].number!=0;i++)
{
if(strcmp(arr[i].word,brr)==0)
{
return i;
}
}
return 0;
}
void Sort(fin *arr) //按出現頻率排序
{
int tmp=0;
char stmp[26]="0";
for(int i=0;arr[i].number != 0;i++)
{
for(int j=i+1;j>0;j--)
{
if(arr[j].number>arr[j-1].number)
{
tmp=arr[j].number;
strcpy(stmp,arr[j].word);
arr[j].number=arr[j-1].number;
strcpy(arr[j].word,arr[j-1].word);
arr[j-1].number=tmp;
strcpy(arr[j-1].word,stmp);
}
}
}
}
void Sort1(fin *arr) //按單詞表排序
{
int tmp = 0;
char stmp[26]="0";
for(int i=0;arr[i].number != 0;i++)
{
for(int j=i+1;j>0;j--)
{
if(strcmp(arr[j-1].word,arr[j].word) < 0)
{
tmp=arr[j].number;
strcpy(stmp,arr[j].word);
arr[j].number=arr[j-1].number;
strcpy(arr[j].word,arr[j-1].word);
arr[j-1].number=tmp;
strcpy(arr[j-1].word,stmp);
}
}
}
}
bool Myisalpha(char *p) //判斷字元是否為字母
{
char arr[54]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'";
for(int i=0;arr[i]!='\0';i++)
{
if(*p==arr[i])
{
return true;
}
}
return false;
}
void Find()
{
fin *arr=(fin *)calloc(1,sizeof(fin));
char brr[26]="0";
fin *crr;
int i=0;
int j=0;
char p='0';
FILE *fp=fopen("2.txt","r");
while(!feof(fp))
{
p=fgetc(fp);
if(Myisalpha(&p))
{
if(isupper(p))
{
p=tolower(p);
}
brr[i]=p;
brr[i+1]='\0';
i++;
}
else
{
if(Find_index (arr,brr)==0)
{
crr=(fin *)realloc(arr,(j+2)*sizeof(fin)); //每次需要記錄新單詞時新增兩個fin格子
arr = crr;
for(int i_a=j+1;i_a<j+2;i_a++) //將新新增的fin格子的number置為0
{
arr[i_a].number=0;
}
if(strcmp("s",brr)!=0&&strcmp("t",brr)!=0)
{
strcpy(arr[j].word,brr);
arr[j].number += 1;
i = 0;
j++;
}
}
else
{
arr[Find_index(arr,brr)].number++;
i = 0;
}
}
}
Sort(arr);
Show(arr);
fclose(fp);
free(arr);
}
int main()
{
Find();
return 0;
}