@[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)一書關於使用二叉排序樹計算英文單詞的頻率。