英文词频分析器
2013-10-02 01:59
295 查看
转载请标明出处:http://blog.csdn.net/u012027907
有时经常有统计一篇文章中有多少个单词,这时候就需要词频分析器来解决了。
基本思想:
将文件中或用户输入的字符串先存起来,然后从第一个字符开始依次向后扫描,遇到字母,则将其先添加到一个字符串中,然后在向后扫描,若还是字母,则将此字符串连接到刚才的字符串中,若不是字母,则刚才的字符串就是一个单词,这样依次扫描完所有字符。当然,在扫描时,还要与已经存储的单词依次比较,若相同则不再添加,刚才那个单词的词数加一即可。
先截个图SeeSee:
我还将查询的结果保存至Access的数据库中,这里就用到ADO访问数据库的问题,上次我已经将ADO连接类(ADOConn)分装好了,这次只拿来用就行了。
代码:
当然用数据结构来存最好了。
主类:
转载请标明出处:http://blog.csdn.net/u012027907
有时经常有统计一篇文章中有多少个单词,这时候就需要词频分析器来解决了。
基本思想:
将文件中或用户输入的字符串先存起来,然后从第一个字符开始依次向后扫描,遇到字母,则将其先添加到一个字符串中,然后在向后扫描,若还是字母,则将此字符串连接到刚才的字符串中,若不是字母,则刚才的字符串就是一个单词,这样依次扫描完所有字符。当然,在扫描时,还要与已经存储的单词依次比较,若相同则不再添加,刚才那个单词的词数加一即可。
先截个图SeeSee:
我还将查询的结果保存至Access的数据库中,这里就用到ADO访问数据库的问题,上次我已经将ADO连接类(ADOConn)分装好了,这次只拿来用就行了。
代码:
void ADOConn::OnInitADOConn() { // CString sysPath = "C:\\fg\\MuscicPlayer\\"; HRESULT hr; ::CoInitialize(NULL); //初始化OLE/COM环境 hr=m_pConnection.CreateInstance("ADODB.Connection"); //创建connection对象 // 在ADO操作中建议语句中要常用try...catch()来捕获错误信息, // 因为它有时会经常出现一些意想不到的错误。 try { if(SUCCEEDED(hr)) { char *dbPath="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=WordData.mdb"; hr=m_pConnection->Open(_bstr_t(dbPath),"","",adModeUnknown); } // _bstr_t strConnect="Provider=SQLOLEDB;Server=LENOVO-PC;DataBase=Study;uid=sa;pwd=zyc123"; // m_pConnection->Open(strConnect,"","",adModeUnknown); } //捕获异常 catch(_com_error e) { e.Description(); } } void ADOConn::ExitConnect() { //关闭记录集和连接 if(m_pRecordset!=NULL) m_pRecordset->Close(); m_pConnection->Close(); //释放环境 ::CoUninitialize(); } _RecordsetPtr& ADOConn::GetRecordSet(_bstr_t bstrSQL) { try { //连接数据库,如果conection对象为空,则重新连接数据库 if(m_pConnection==NULL) OnInitADOConn(); //创建记录集对象 m_pRecordset.CreateInstance(__uuidof(Recordset)); //取得表中的记录 m_pRecordset->Open(bstrSQL,m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText); } catch(_com_error e) { e.Description(); } //返回记录集 return m_pRecordset; } BOOL ADOConn::ExecuteSQL(_bstr_t _bstrSQL) { _variant_t RecordsAffected; try { //是否已连接数据库 if(m_pConnection==NULL) OnInitADOConn(); m_pConnection->Execute(_bstrSQL,NULL,adCmdText); return true; } catch(_com_error e) { e.Description(); return false; } }
当然用数据结构来存最好了。
///////////////存放分出的所有单词的结构体///////// typedef struct WordStore { char word[30]; }wordstore; /////////存储排好序的单词及个数的结构体/////////// typedef struct WordStoreAll { float frequency; int number; char word[30]; }wordstoreall;
主类:
////////////////////////////////////////// class ReadWord { int AllWord; int Count; bool AddTrue; wordstore WordNode[MAX]; wordstoreall Word[MAX]; /////数据库操作使用 ADOConn m_AdoConn; _RecordsetPtr m_pRecordset; _ConnectionPtr m_pConnection; char *tablename; public: int Choice; public: ReadWord(); int GetCount(){ return Count;} bool GetAddTrue(){return AddTrue;} char *ReadFromText(); char *ReadFromScreen(); void strcopy(char *dest,const char *sour); void Transform(char *str); void GetEveryWord(); void Countword(); void Frequency(); void Order(); void Print(int X); void color(int a); ///-------数据库操作---------------- void IsAddToAccess(); //判断用户是否将分析结果添加到数据库 void AddToAccess(); //将分析结果添加到数据库 void Select(); //查询数据库中的数据 void CreateTable(); void GetTableName(int n); void ReadTableName(); void WriteTNameToFile(); };
/////////////////////////////// #include "Readword.h" /////////////////////////////// ///////构造函数////////////// ReadWord::ReadWord() { AddTrue = false; } //////////////////加点颜色SeeSee///////////////////////////// void ReadWord::color(int a) //颜色函数 { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a); } /////////////从屏幕上读取信息到字符串中///////////// char *ReadWord::ReadFromScreen() { char *string; string = (char*)malloc(1000); printf("请输入:"); // fflush(stdout); gets(string); return string; } ///////////////////////////////////////// /////////////从文件中读取信息到字符串中///////////// char *ReadWord::ReadFromText() { FILE *fp; char *string; char FileName[30]; string = (char*)malloc(5000); if(NULL == string) { printf("内存分配失败!\n"); return NULL; } printf("请输入文件名(不用输后缀名):"); scanf("%s",FileName); // gets(FileName); strcat(FileName,".txt"); fp = fopen(FileName,"rb"); if( NULL == fp) { printf("文件打开错误\n"); return NULL; } fgets(string,5000,fp); fclose(fp); return string; } ////////////////将非单词的字符转化为空格//////////// void ReadWord::Transform(char *str) { while(*str != '\0') { if(*str<'a'||*str>'z') *str=' '; str++; } } //////////////拷贝函数///////////////// void ReadWord::strcopy(char *dest,const char *sour) { while(*sour != '\0') { *dest++=*sour++; } *dest='\0'; } //////////////将每个单词分离出来////////////////// void ReadWord::GetEveryWord() { char tempw[30]; char tempc[2]; char *String; bool m_flag=false; int i=0,n=0; if(1 == Choice) String = ReadFromText(); else String = ReadFromScreen(); strlwr(String); ///将大写字母转化为小写字母 Transform(String); while(1) { if(*String != '\0') { tempc[0]=*String; if(' ' != *String) { tempw[i++]=tempc[0];m_flag = true; } else { if(m_flag) { m_flag = false; tempw[i]='\0'; strcopy(WordNode .word,tempw); n++; for(;i>=0;i--) tempw[i]=0; i=0; } } } else if(*(--String) != ' ') //这时为了将文件最后一个单词因为没加标点,而未能统计的最后一个单词统计进去 { tempw[i]='\0'; strcopy(WordNode .word,tempw); n++; for(;i>=0;i--) tempw[i]=0; i=0; break; } else break; String++; } AllWord=n; //得到分离出的总词数 } //////////////////////对提取出的所有单词计数//////// void ReadWord::Countword() { int i,j; int count=0,m_flag=0; for(i=0;i<AllWord;i++) Word[i].number=1; for(i=0;i<AllWord;i++) { m_flag=0; for(j=0;j<AllWord;j++) { if(!strcmp(Word[j].word,WordNode[i].word)) //若有相同的单词,其相应的number加一 { Word[j].number++;m_flag=1;} } if(0 == m_flag) //若原有的单词中没有相同的,则添加此单词到Word中 { strcopy(Word[count].word,WordNode[i].word); count++; } } Count=count; } ////////////////计算每个单词的频率////////////// void ReadWord::Frequency() { int i; for(i=0;i<Count;i++) { Word[i].frequency=(float)Word[i].number/Count; } } ////////////////冒泡排序///////////////////////// void ReadWord::Order() { char tempstr[30]; int tempnum; float tempfre; int m,n; for(m=1;m<Count;m++) for(n=0;n<Count-m;n++) { if(strcmp(Word .word,Word[n+1].word)>0) { //////交换单词 strcopy(tempstr,Word .word); strcopy(Word .word,Word[n+1].word); strcopy(Word[n+1].word,tempstr); ////////交换词数 tempnum = Word .number; Word .number = Word[n+1].number; Word[n+1].number = tempnum; /////////交换频率 tempfre = Word .frequency; Word .frequency = Word[n+1].frequency; Word[n+1].frequency = tempfre; } } } ///////////////////输出结果////////////////////// void ReadWord::Print(int X) { int i; printf("对该文本的词频分析如下:\n"); printf("序号\t单词\t 个数\t频率\n"); for(i=0;i<X;i++) { printf("%-3d\t%-10s\t%d\t%.2f%%\n",i+1,Word[i].word,Word[i].number,Word[i].frequency*100); } } ///////////////从数据库中选择查询结果////////////// void ReadWord::Select() { m_AdoConn.OnInitADOConn(); //初始化链接库类 // char *sql="Select * From Wordtable"; char *q=" "; char Sql[50]; char *Sql1 ="SELECT * FROM "; strcopy(Sql,Sql1); strcat(Sql,tablename); strcat(Sql,q); m_pRecordset=m_AdoConn.GetRecordSet((_bstr_t)Sql); //打开并获得记录集 m_pConnection.CreateInstance(__uuidof(Connection)); //创建connection对象 _variant_t var; char strword[30]; int number; double frequen; int i=0; try { if(!m_pRecordset->adoBOF) //表中数据不为空,将记录及指针移到第一条 m_pRecordset->MoveFirst(); else { printf("\n数据表为空!\n"); m_AdoConn.ExitConnect(); return ; } printf("对该文本的词频分析如下:\n"); printf("序号\t单词\t 个数\t频率\n"); // 读入库中各字段并输出 while(!m_pRecordset->adoEOF) { var = m_pRecordset->GetCollect("Word"); //获得一条记录的Word字段信息 if(var.vt != VT_NULL) strcopy(strword,(LPCSTR)_bstr_t(var)); var = m_pRecordset->GetCollect("Num"); //获得一条记录的Num字段信息 if(var.vt != VT_NULL) number = var.intVal; var = m_pRecordset->GetCollect("Frequency"); if(var.vt != VT_NULL) frequen = var.dblVal; printf("%-3d\t%-10s\t%d\t%.2lf%%\n",i+1,strword,number,frequen*100); i+=1; m_pRecordset->MoveNext(); } } catch(_com_error *e) { // AfxMessageBox(e->ErrorMessage()); e->Description(); } m_AdoConn.ExitConnect(); } //////////////////用户是否同意将结果添加到数据库///////// void ReadWord::IsAddToAccess() { char button; printf("\n是否将结果添加到数据库?是按[Y],否按其他键。\n"); fflush(stdin); scanf("%c",&button); if(button == 'Y' || button == 'y') { AddTrue = !AddTrue; GetTableName(1); CreateTable(); AddToAccess(); } } ////////////////将结果添加到数据库中///////////////////////// void ReadWord::AddToAccess() { m_AdoConn.OnInitADOConn(); char *q=" "; char Sql[50]; char *Sql1 ="SELECT * FROM "; strcopy(Sql,Sql1); strcat(Sql,tablename); strcat(Sql,q); m_pRecordset=m_AdoConn.GetRecordSet((_bstr_t)Sql); //打开并获得记录集 m_pConnection.CreateInstance(__uuidof(Connection)); //创建connection对象 _variant_t var; int i; try { if(AddTrue) { for(i=0;i<Count;i++) { m_pRecordset->AddNew(); m_pRecordset->PutCollect("Word",_variant_t(Word[i].word)); m_pRecordset->PutCollect("Num",_variant_t((long)Word[i].number)); m_pRecordset->PutCollect("Frequency",_variant_t((float)Word[i].frequency)); m_pRecordset->Update(); } } printf("\n添加成功!\n\n"); m_AdoConn.ExitConnect(); } catch(...) { printf("操作失败\n"); } } //////////////将用户输入的表名存储到文件中//////////////// void ReadWord::WriteTNameToFile() { char *Table,*str=" "; Table = (char*)malloc(20); strcopy(Table,str); strcat(Table,tablename); strcat(Table,str); FILE *fp; if((fp = fopen("TableNameList.txt","ab+")) == NULL) { printf("不能打开文件\n"); return; } if(fwrite(Table,strlen(Table)*sizeof(char),1,fp) != 1) printf("文件写出错!\n"); fclose(fp); } ////////////////////存文件中读取表名//////////////////////// void ReadWord::ReadTableName() { FILE *fp; char *string; char *FileName="TableNameList.txt"; string = (char*)malloc(300); if(NULL == string) { printf("内存分配失败!\n"); return; } fp = fopen(FileName,"rb"); if( NULL == fp) { printf("文件打开错误\n"); return; } fgets(string,300,fp); fclose(fp); printf("可供查询的表名如下:\n"); printf("%s\n",string); } //////////////获得要创建表的名称或获得要查询表的名称//////////// void ReadWord::GetTableName(int n) { tablename = (char*)malloc(20); fflush(stdin); if(1 == n) { printf("请输入要创建的表名:"); gets(tablename); WriteTNameToFile(); } else { ReadTableName(); printf("请输入您要查询的表名:"); gets(tablename); /////////判断 } } //////////////////////创建表////////////////// void ReadWord::CreateTable() { m_AdoConn.OnInitADOConn(); // _bstr_t sql; char Sql[100]; char *Sql1 = "CREATE TABLE "; char *Sql2 = " (Word varchar(30),Num int,Frequency float)"; strcopy(Sql,Sql1); strcat(Sql,tablename); strcat(Sql,Sql2); if(!m_AdoConn.ExecuteSQL((_bstr_t)Sql)) { printf("\n创建表失败!\n"); return; } m_AdoConn.ExitConnect(); }
转载请标明出处:http://blog.csdn.net/u012027907
相关文章推荐
- python 统计TXT中的英文词频
- 统计英文单词词频
- 软件体系结构课程设计:词频统计程序(包含英文单词和数字double,int)
- 学以致用——英文姓名高词频分析-使用Excel制作高频词标签云(VBA)
- 用ruby统计英文文章的词频
- 使用Python+NLTK实现英文单词词频统计
- 比较lucene各种英文分析器Analyzer
- 1st 英文文章词频统计
- C语言实现英文文本词频统计
- 统计英文文本中的词频
- 组合数据类型练习,英文词频统计实例
- 实验二-2 Eclipse&Hadoop 做英文词频统计进行集群测试
- 英文单词词频统计
- 如何利用python统计英文文章词频
- 使用Lucene词频统计与d3.cloud展示的中文英文词云系统
- 组合数据类型和英文词频统计实例
- c++ 统计英文文本中每个单词的词频并且按照词频对每行排序
- 计算英文文章词频的两种方法
- 组合数据类型练习,英文词频统计实例
- python 统计序列中元素的出现频度\统计英文文章的词频