一、前言
在之前寫過一個詞頻統計的C語言課設,別人說你一個大三的怎么寫C語言課程,我只想說我是先學習VB,VB是我編程語言的開始,然后接觸到C語言及C++;再后來我是學習C++,然后反過來學習C語言,記得那時候自己在C++中沒有好好學習,考試之前瘋狂的背代碼,然后過了。后來學習C語言的時候,自己知道基礎很重要,然后認真學習。這WC這回自己就輕車熟路,記得那時候丁國輝課設老師,問我有多少是自己寫的,我說有80%自己寫的,然后他讓我當場給程序增加一個總的單詞數和每一個單詞的頻率,當時記得自己在旁邊改了十分鍾左右才弄完,因為自己太大意,出現了低級錯誤,然后自己還一直沒有發現。自己學習的map來寫詞頻統計map<string,int>mp,發現更快。代碼更短,效率更高。
二、分析
1、在命令行中直接輸入一串英文字符串,統計單詞的個數,自己是C語言學習的一個初學者,在C語言機考中自己總是會很快的敲出來。
#include <iostream> #include<cstdio> #include<cstdlib> using namespace std; //統計單詞的個數 int main() { char a; int count=0; while((a=getchar())!='\n') { if(a==' ') count++; } cout << count+1 << endl; return 0; }
2、使用的map的寫的統計單詞的出現的次數
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<map> #include<string.h> using namespace std; int main() { cout<<"輸入以0結尾"<<endl; map<string,int>mp; string str1; while(str1!="0") { cin>>str1; mp[str1]++; } map<string,int>::iterator iter; for(iter=mp.begin();iter!=mp.end();iter++) { if(iter->first!="0") //字符的判斷與0 cout<<iter->first<<" "<<iter->second<<endl; } return 0; }
3、在文件中怎么讀取字符呢。我們定義一個文件指針
FILE *fp; //文件指針
使用的時候記得“讀”就行打開了就要關閉
if((fp=fopen(name,"r+"))==NULL){ printf("Open the file failure...\n"); exit(0); } fp=fopen(name,"r"); wordCount(); fclose(fp);
4、定義了一個結構體,使用鏈表的存儲結構
typedef struct word //連表 單詞結構 { char w[Word_Max]; //單詞 int count; //個數 struct word *next; }link;
5、指針指向的字符是否為字母還是其他的格式字符
int isnotWord(char a) //判斷是否為字母 { if(a <= 'z' && a >= 'a') { littleletter++; return 0; } else if(a <= 'Z' && a >= 'A') { bigletter++; return 0; } else if(a==' ') { space++; return 1; } else if(a>='1'&&a<='9') { number++; return 1; } else if(a=='\n') { hang_num++; return 1; } else { other++; return 1; } }
6、如果是添加單詞,就要記錄該單詞,下次指針再次指到,字符串比較strcmp(str1,str2)==0,如果不是就要動態存儲分配malloc。
void addWord(char *w1) //添加單詞 { link *p1,*p2; //if(w1[0] <= 'Z' && w1[0] >= 'A') //轉成小寫字母 //{ // w1[0]+=32; //} for(p1=head;p1!=NULL;p1=p1->next) //判斷單詞在連表中是否存在 { if(!strcmp(p1->w,w1)) { p1->count++; //存在就個數加1 return; } } p1=(struct word *)malloc(sizeof(word));//不存在添加新單詞 strcpy(p1->w,w1); p1->count=1; p1->next=NULL; count++; //總的單詞數加加 if(head==NULL) { head=p1; } else { for(p2=head;p2->next!=NULL;p2=p2->next); p2->next=p1; } }
7、單詞統計函數
void wordCount() //統計單詞 { int i=0,j=0; char word[Word_Max],c; while(!feof(fp)) { fscanf(fp,"%c",&c); if(isnotWord(c)) { word[j]='\0'; if(j>0) { addWord(word); } j=0; } else { word[j]=c; j++; } //count9(word); i++; } }
三、運行結果及源代碼
文件test.txt默認路徑是程序編譯下的文件夾中。
有人會說,”I“不是出現了嗎?我統計的個數是0-4(不包括0和4),而“I”這個單詞出現的次數是5,不在范圍之內。注意:是.txt中有自動換行功能,所以我統計的是自己用回車鍵換行的行數,這個才是真正的文本的行數。
#include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; #define Name_Max 30 //文件名最大長度 #define Word_Max 60 //每個單詞最大長度 typedef struct word //連表 單詞結構 { char w[Word_Max]; //單詞 int count; //個數 struct word *next; }link; int count=0; link *head=NULL; //連表頭 FILE *fp; //文件指針 int bigletter=0,littleletter=0,space=0,number=0,other=0,hang_num=0;; int isnotWord(char a) //判斷是否為字母 { if(a <= 'z' && a >= 'a') { littleletter++; return 0; } else if(a <= 'Z' && a >= 'A') { bigletter++; return 0; } else if(a==' ') { space++; return 1; } else if(a>='1'&&a<='9') { number++; return 1; } else if(a=='\n') { hang_num++; return 1; } else { other++; return 1; } } void addWord(char *w1) //添加單詞 { link *p1,*p2; //if(w1[0] <= 'Z' && w1[0] >= 'A') //轉成小寫字母 //{ // w1[0]+=32; //} for(p1=head;p1!=NULL;p1=p1->next) //判斷單詞在連表中是否存在 { if(!strcmp(p1->w,w1)) { p1->count++; //存在就個數加1 return; } } p1=(struct word *)malloc(sizeof(word));//不存在添加新單詞 strcpy(p1->w,w1); p1->count=1; p1->next=NULL; count++; //總的單詞數加加 if(head==NULL) { head=p1; } else { for(p2=head;p2->next!=NULL;p2=p2->next); p2->next=p1; } } void wordCount() //統計單詞 { int i=0,j=0; char word[Word_Max],c; while(!feof(fp)) { fscanf(fp,"%c",&c); if(isnotWord(c)) { word[j]='\0'; if(j>0) { addWord(word); // count9(word); //count1(word,); } j=0; } else { word[j]=c; j++; } //count9(word); i++; } } void readWord() //讀取文件中的單詞 { char name[Name_Max]; printf("請出入要讀取的單詞文件名[如:test.txt]:"); scanf("%s",name); getchar(); if((fp=fopen(name,"r+"))==NULL){ printf("Open the file failure...\n"); exit(0); } fp=fopen(name,"r"); wordCount(); fclose(fp); } void showWord(int a,int b) //顯示單詞統計情況 { link *p; printf("個數\t單詞\t頻率\n"); for(p=head;p!=NULL;p=p->next) { if((p->count > a)&&(p->count < b)) { printf("%s\t %d\t %.2f\n",p->w,p->count,(float)(p->count)/count); } } printf("總的單詞數:%d\n",count); printf("總共有%d行\n",hang_num+1); printf("總共有%d字符\n",bigletter+littleletter+space+number+other); printf("大寫字母個數:%d 小寫字母個數:%d 空格個數%d 數字個數%d 其他個數%d\n",bigletter,littleletter,space,number,other); } int main() { readWord(); int a,b; printf("請輸入閾值a和b[如:2 10]:"); scanf("%d %d",&a,&b); getchar(); showWord(a,b); getchar(); }
