1. 程式人生 > >如何統計一本英文書(比如簡愛)中出現次數最多的前1000個單詞

如何統計一本英文書(比如簡愛)中出現次數最多的前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;
}