软件工程之个人项目--词频统计
????? 不得不說對于菜鳥級的我,這是一次心酸的經歷啊。。。自打接到王老師布置的這個任務(個人項目)之后,我心里一直在想著自己要用哪種語言來完成我的任務。以前多多少少寫過一些程序的,這又想起了數據庫小學期與永哥和小強哥一起奮斗的日子來了,和大牛一起合作就是長見識,哈哈!
???? 好吧,介紹一下題目,對一個英文文本進行詞頻統計,并把出現頻率最高的10個詞打印出來。
???? 發愁是肯定的,努力也是肯定的,既然對一個英文文本進行詞頻統計,那么肯定會用到文件的讀寫函數,所以先找到了c語言課本,對這一部分的知識做了一下系統地復習。并且對該部分的知識做了一個小小的總結,雖然不是很全面吧,但是是自己對知識的深入理解。當然這對我們班的神人來說就是小case了,所以還是很慚愧滴!
???? 對文件的讀寫操作搞懂了之后呢,就要設計自己的思路了。首先,定義一個結構體,(想必,我的同學們也有好多用結構體的...)
1 struct wordcount//定義一個結構體Wordcount 2 { 3 char *word; 4 int count; 5 struct wordcount *next; 6 };然后定義了一些指向結構體變量的指針,和緩沖區用來存放從文本文件中獲取的內容。然后運用isalpha()來判斷讀到緩沖區的內容是否為字母。
?????/*?函數:isalpha
原型:int isalpha(int ch)
用法:頭文件加入#include <cctype>(舊版本的編譯器使用<ctype.h>)
功能:判斷字符ch是否為英文字母,當ch為英文字母a-z或A-Z時,在標準c中相當于使用“isupper(ch)||islower(ch)”做測試,返回非零值,否則返回零。*/
???? 之后就是判斷緩沖區中的單詞有沒有超過規定的最大限度,以及把大寫字母轉換為小寫字母等等。部分代碼如下
?
用strcpy()函數來判斷是否和buff內的單詞相同,若相同,則count+1
1 while (wc)//如果有的話則計數加1 2 { 3 if (strcmp(wc->word,buff)==0) 4 { 5 wc->count=wc->count+1; 6 isfinded=1; 7 break; 8 } 9 else 10 wc=wc->next; 11 }?
對出現次數最高的10個詞進行排序則可能弱了一些,我選用的是交換排序,所以效率會慢了一些。自然所用的時間就會長好多了(和那些大牛級的任務了)。下面是全部的代碼:
#include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <string.h>#define MAXLEN 30struct wordcount//定義一個結構體Wordcount {char *word;int count;struct wordcount *next; };struct wordcount *head,*wc,*sort,*headsort; char buff[MAXLEN]; char *zs_c;//buf[]數組用來存放英文字母 int buff_count=0, isfinded;int main() {FILE *fp;char ch;int i;int k;char filename[20];printf("請輸入文件名:\n");scanf("%s",filename);if ((fp=fopen(filename,"r"))==NULL) {printf("不能打開該文件!\n");exit(0);}while ((ch=fgetc(fp))!=EOF)//讀取英文文本中的內容if (isalpha(ch)){buff[buff_count++]=tolower(ch);//判斷是否為字母若果是則把它放到數組Buff[]if (buff_count>=MAXLEN){printf("單詞長度超過最大限度!\n");//判斷單詞的長度是否超過最長限度 fclose(fp);return -1;}}else{//若果不是字母,且buff[]中沒有單詞的話則把其放到Wordcount link中if (buff_count!=0){buff[buff_count]='\0';wc=head;isfinded=0;while (wc)//如果有的話則計數加1 {if (strcmp(wc->word,buff)==0){wc->count=wc->count+1;isfinded=1;break;}elsewc=wc->next;}if (isfinded==0) {zs_c=(char *)malloc(buff_count);if (zs_c==0){printf("錯誤!: zs_c !\n");fclose(fp);exit(0);}memcpy(buff,zs_c,buff_count);wc=(struct wordcount *)malloc(sizeof(struct wordcount));if (wc==0){printf("分配有誤!\n");fclose(fp);exit(0);}wc->word=zs_c;wc->count=1;wc->next=head;head=wc;}buff_count=0;}}fclose(fp);if (head)//對單詞進行排序 {sort=head->next;head->next=0;while (sort){wc=sort;sort=sort->next;if ((wc->count) > (head->count)){wc->next=head->next;head=wc;}else{headsort=head;while ((headsort->next) && (headsort->next->count > wc->count ))//交換進行排序 {headsort->count=headsort->next->count;wc->next->count=headsort->next->count;wc->next->count=headsort->count;headsort->word=headsort->next->word;wc->next->word=headsort->next->word;wc->next->word=headsort->word;}}}}while (head)//對結果進行輸出 {wc=head;head=head->next;printf("序號\t單詞\t頻率\n");for(i=1;i<11;i++)printf("NO%d\t%s\t %d\n",i,wc->word,wc->count);}return 0; }?運行結果:
?
?
個人工作總結:
????? 實話說來對于好久沒有碰過程序的我來說不得不說這是很困難的。
??????2.22就開始構思如何實現這個問題,開始進行咨詢,并開始復習文件的讀取。
??????2.27上機時間(2:00--4:00)開始寫程序,事實表明情況是不樂觀的,此時多么希望神可以拯救我啊!(抓狂)。后來了解到,用trie樹,map實現起來效率比較高,所以對這兩種方法進行了查詢,但是能力有限,所以還是沿用了最先的想法,周五自打吃完晚飯,就開始繼續調試程序,就因為文件無法讀取這個問題困擾了一晚上,最終和嬌哥交流后,(因為她也遇到了相同的問題,難姐難妹啊),才知道是文件默認的格式就是.txt,是自動隱藏的,還以為是自己安裝的vc有問題呢或者和電腦本身有關系,看來寫程序這個東西是要和同仁交流的!!!。
???? 周六晚8:00又出現了一個大大的問題那就是死循環,所以那更是一個痛苦,程序的調試是必須的了,終于,發現了!原來是在進行數據交換的時候丟了一個指針。本來想使用argv傳遞參數的,argv[0]是執行的該文件,argv[1]是傳遞的第二個參數,即在屏幕上輸入的第一個內容,本來是想用這種方法來獲取文件的名稱的,但是失敗了,所以又改用了原來c語言傳統的文件讀取方式。
????? 不得不承認我的這個工程效率是不高的,比如說排序用到的算法啊,(有時間一定要再研究一下)如果文本的大小再大些的話,速度是相當的慢了就。自己的能力還不是很高,自己都覺得著急了,因為對trie樹也進行了一定的學習,我想自己接下來能否可以用這種數據結構來實現,最讓我崇拜的就是輝哥的hashtable了,自己一定要對這些知識進行學習。多學習,多聯系,這是我對寫程序的深刻體會!
?
?
?
轉載于:https://www.cnblogs.com/zsjy/p/3576384.html
總結
以上是生活随笔為你收集整理的软件工程之个人项目--词频统计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 触发器的创建、修改和删除
- 下一篇: QM课程02-外部功能