c語(yǔ)言實(shí)現(xiàn)詞頻統(tǒng)計(jì)的簡(jiǎn)單實(shí)例
需求:
1.設(shè)計(jì)一個(gè)詞頻統(tǒng)計(jì)軟件,統(tǒng)計(jì)給定英文文章的單詞頻率。
2.文章中包含的標(biāo)點(diǎn)不計(jì)入統(tǒng)計(jì)。
3.將統(tǒng)計(jì)結(jié)果以從大到小的排序方式輸出。
設(shè)計(jì):
1.因?yàn)槭强鐚?zhuān)業(yè)0.0···并不會(huì)c++和java,只能用僅學(xué)過(guò)的C語(yǔ)言進(jìn)行編寫(xiě),還是挺費(fèi)勁的。
2.定義一個(gè)包含單詞和頻率兩個(gè)成員的結(jié)構(gòu)體來(lái)統(tǒng)計(jì)詞頻(進(jìn)行了動(dòng)態(tài)分配內(nèi)存,可以處理較大文本)。
3.使用fopen函數(shù)讀取指定的文檔。
4.使用fgetc函數(shù)獲取字符,再根據(jù)取得的字符是否是字母進(jìn)行不同的處理。
5.采用快速排序法對(duì)統(tǒng)計(jì)結(jié)果進(jìn)行排序。
5.將整個(gè)統(tǒng)計(jì)結(jié)果循環(huán)輸出。
部分代碼:
結(jié)構(gòu)體定義:
struct fre_word { int num; char a[18]; };
分配初始內(nèi)存:
struct fre_word *w; w=(struct fre_word *)malloc(100*p*sizeof(struct fre_word));//給結(jié)構(gòu)體分配初始內(nèi)存
讀取文本:
printf("輸入讀入文件的名字:"); scanf("%s", filename); //輸入需要統(tǒng)計(jì)詞頻的文件名 if((fp=fopen(filename, "r"))==NULL) { printf("無(wú)法打開(kāi)文件\n"); exit(0); }
單詞匹配:
/****************將單詞出現(xiàn)次數(shù)設(shè)置為1****************************/ for(i=0;i<100;i++) { (w+i)->num=1; } /****************單詞匹配****************************************/ i=0; while(!feof(fp))//文件尚未讀取完畢 { ch=fgetc(fp); (w+i)->a[j]='\0'; if(ch>=65&&ch<=90||ch>=97&&ch<=122) //ch若為字母則存入 { (w+i)->a[j]=ch; j++; flag=0; //設(shè)標(biāo)志位判斷是否存在連續(xù)標(biāo)點(diǎn)或者空格 } else if(!(ch>=65&&ch<=90||ch>=97&&ch<=122)&&flag==0) //ch若不是字母且上一個(gè)字符為字母 { i++; j=0; flag=1; for(m=0;m<i-1;m++) //匹配單詞,若已存在則num+1 { if(stricmp((w+m)->a,(w+i-1)->a)==0) { (w+m)->num++; i--; } } } /****************動(dòng)態(tài)分配內(nèi)存****************************************/ if(i==(p*100)) //用i判斷當(dāng)前內(nèi)存已滿 { p++; w=(struct fre_word*)realloc(w,100*p*(sizeof(struct fre_word))); for(n=i;n<=100*p;n++) //給新分配內(nèi)存的結(jié)構(gòu)體賦初值 (w+n)->num=1; } }
快速排序:
void quick(struct fre_word *f,int i,int j) { int m,n,temp,k; char b[18]; m=i; n=j; k=f[(i+j)/2].num; //選取的參照 do { while(f[m].num>k&&m<j) m++; // 從左到右找比k小的元素 while(f[n].num<k&&n>i) n--; // 從右到左找比k大的元素 if(m<=n) { //若找到且滿足條件,則交換 temp=f[m].num; strcpy(b,f[m].a); f[m].num=f[n].num; strcpy(f[m].a,f[n].a); f[n].num=temp; strcpy(f[n].a,b); m++; n--; } } while(m<=n); if(m<j) quick(f,m,j); //運(yùn)用遞歸 if(n>i) quick(f,i,n); }
結(jié)果輸出:
for(n=0;n<=i;n++) { printf("文檔中出現(xiàn)的單詞:"); printf("%-18s",(w+n)->a); printf("其出現(xiàn)次數(shù)為:"); printf("%d\n",(w+n)->num); }
測(cè)試用例:
看了之前同學(xué)的博客以及老師的評(píng)論,就使用了較長(zhǎng)的文本進(jìn)行測(cè)試,用的是奧巴馬就職演講稿。
部分測(cè)試結(jié)果:
以上這篇c語(yǔ)言實(shí)現(xiàn)詞頻統(tǒng)計(jì)的簡(jiǎn)單實(shí)例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)- 解析最少換車(chē)次數(shù)的問(wèn)題詳解
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)- 解析最少換車(chē)次數(shù)的問(wèn)題詳解2013-05-05C++ deque與vector對(duì)比的優(yōu)缺點(diǎn)
這篇文章主要介紹了C++中deque與vector相比的優(yōu)勢(shì)與劣勢(shì),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01Qt編寫(xiě)地圖實(shí)現(xiàn)實(shí)時(shí)動(dòng)態(tài)軌跡效果
實(shí)時(shí)動(dòng)態(tài)軌跡主要是需要在地圖上動(dòng)態(tài)顯示GPS的運(yùn)動(dòng)軌跡,也是編寫(xiě)地圖時(shí)一個(gè)重要的功能。本文將利用Qt實(shí)現(xiàn)這一功能,需要的可以參考一下2022-02-02基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的掃雷小游戲
這篇文章主要為大家詳細(xì)介紹了基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11C++ 類(lèi)的賦值運(yùn)算符''''=''''重載的方法實(shí)現(xiàn)
這篇文章主要介紹了C++ 類(lèi)的賦值運(yùn)算符'='重載的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02