软件工程-构建之法 WordCount小程序 统计文件中字符串个数,单词个数,词频,行数
一、前言
在之前写过一个词频统计的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(); }
文中有错误的地方希望指出,共同进步