使用C语言分析分析英文字符串中的单词
@[TOC] 使用C语言分析分析英文字符串中的单词
分析英文字符串时会产生的问题
比如一句英文: we eat dinner at four o’clock,noodles is delicious. 要提取这句英文字符串的单词时,要区分以下四个英文标点字符:
1. 空格
2. ‘
3. ,
4. .
以便得到英文单词:
1. we
2. eat
3. dinner
4. at
5. four
6. o’clock
7. noodles
8. is
9. delicious
简化条件
为了简化编程的复杂度,目前仅区分以下三个英语标点字符:
1. 空格
2. ,
3. .
此时 o’clock 可能分被解为两个字符: o
与clock
会得到以下英文单词:
1. we
2. eat
3. dinner
4. at
5. four
6.o
7.clock
8. noodles
9. is
10. delicious
分析方法
1.分析字符串的第一个单词
2.分析字符串的最后一个单词
3.分析字符串除第一个单词和最后一个单词以外的其它单词
详细分析
将字符串去掉o’简化为如下字符串:
we eat dinner at four clock,noodles is delicious.
- 第一个单词:we
起始位置:字符串的0索引
终止位置:终止位置的下一个字符为空格 - 最后一个单词:delicious
起始位置:起始位置的上一个字符为空格
终止位置:终止位置的下一个字符为非字母单词 - 其余的单词,比如:at
起始位置:起始位置的上一个字符为空格
终止位置:终止位置的下一个字符为空格
C++代码
C++代码如下
main.cpp
// main.cpp
#include <iostream>
#include<string.h>
#include"VString.h"
int isMeanChar(char c);
const char* substr(const char* pString,int begin,int end);
int main(int argc, char** argv) {
int i = 0;
int j = 0;
int k = 0;
int bindex=0;
int eindex=0;
int begin[1024]={-1};
int end[1024]={-1};
//char word[1024]="now is the time for all good men to come to the aid of their party.";
char word[1024]="we eat dinner at four o'clock,noodles is delicious.";
for(int i=0;i<1024;i++) {
if(i>strlen(word)){
break;
}
if(i==0){
begin[bindex]=i;
bindex++;
}
if( (i-1)>0 && isMeanChar(*(word+i-1))<0 && isMeanChar(*(word+i))>0 ){
/*从非字符到字符,是一个单词的起始*/
begin[bindex]=i;
bindex++;
}
if( (i+1<=strlen(word)) && isMeanChar(*(word+i))>0 && isMeanChar(*(word+i+1))<0 ){
/*从字符到非字符,是一个单词的结束*/
end[eindex]=i;
eindex++;
}
}
for(j=0;j<=20;j++){
printf("%d:[%d,%d]\n",j+1,begin[j],end[j]);
}
VString *wordString=new VString();
bindex=0;
eindex=0;
while(end[k]!=0){
printf("%s\n",wordString->substr(word,begin[k],end[k]));
k = k + 1;
}
delete wordString;
wordString = NULL;
return 0;
}
int isMeanChar(char c){
int n=(int)c;
if( (n>=48) && (n<=57) ){
/*阿拉伯数字*/
return 1;
}
if( (n>=65) && (n<=90) ){
/*大写英文字母*/
return 1;
}
if( (n>=97) && (n<=122) ){
/*小写英文字母*/
return 1;
}
return -1;
}
VString.h
#ifndef _VSTRING_H_
#define _VSTRING_H_
//#define NULL 0x0
#define ARRAY_SIZE 16
#define ARRAY_SIZE_512K 512*1024
#define ARRAY_SIZE_1M 1024*1024
#include<string.h>
class VString{
public:
VString(){
this->pString = NULL;
}
~VString(){
deleteMemory();
}
public:
char* substr(const char* pString, int begin, int end);
protected:
char *pString;
private:
int isNull(const char* pString){
if ((pString == NULL)||((unsigned int)pString==0xcccccccc)){
return 0;
}
else{
return 1;
}
}
//分配内存空间
char* newMemorySpace(int size);
void zeroMemory(int size);
void deleteMemory();
};
#endif
VString.cpp
#include "VString.h"
char* VString::substr(const char* pString,int begin,int end){
int i,j;
int size=end-begin+1;
char* pSubstr=newMemorySpace(size+1);
for( i=begin, j=0;i<=end;i++,j++){
pSubstr[j]=pString[i];
}
pSubstr[j]=0x0;
return pSubstr;
}
void VString::zeroMemory(int size){
for (int i = 0; i < size; i++){
*(this->pString + i) = 0x0;
}
}
char* VString::newMemorySpace(int size){
if(isNull(this->pString)!=0){
delete this->pString;
this->pString = NULL;
}
this->pString = new char[size];
zeroMemory(size);
return this->pString;
}
void VString::deleteMemory(){
if (isNull(this->pString) != 0){
delete this->pString;
this->pString = NULL;
}
}
测试结果
参考
代码的开发灵感来于《C程序设计语言(第二版是 新版)》(The C Programming Language Second Edition)一书关于使用二叉排序树计算英文单词的频率。