📄 splitword.c
字号:
while ( i > 1 )
{
for ( j = MAX_CWORD_LEN ; j >= 2 ; j -=2 )
{ //最长xxx个汉字
if ( i < j )
continue;
l = 0 ;
for ( k = i - j ,l = 0 ; k < i ; k ++,l ++ )
strChar[l] = strText[k];
strChar[l] = '\0';
if ( 8 == j )
{//4个字时,无论哪种情况下都要比较前两个及后两个,防止"后三字是一个词,但第一个字跟再前一个字是一个词",同时可以捕获成词由两个词组成的
//如,让“我看看怒火凤凰",应该是"怒火"+凤凰,而不是"怒"+"火凤凰"
strChar1[0] = strChar[0];strChar1[1] = strChar[1];
strChar1[2] = strChar[2];strChar1[3] = strChar[3];
strChar1[4] = '\0';
strChar2[0] = strChar[4];strChar2[1] = strChar[5];
strChar2[2] = strChar[6];strChar2[3] = strChar[7];
strChar2[4] = '\0';
bFound = searchWord(strChar1 , 4 ); //先取前两个字比较
if ( TRUE == bFound )
{
bFound = searchWord(strChar2 , 4 ); //再取后两个字比较
if ( TRUE == bFound )
{ //后两个是词
addSegWord(strChar1,4); //则,前后两个字,当做两个词加入
addSegWord(strChar2,4);
i -= j ;
break;
}
}
else
{ //再比较前三字是否一个词
strChar3[0] = strChar[0];strChar3[1] = strChar[1];
strChar3[2] = strChar[2];strChar3[3] = strChar[3];
strChar3[4] = strChar[4];strChar3[5] = strChar[5];
strChar3[6] = '\0';
bFound = searchWord(strChar3,6);
if ( TRUE == bFound )
{ //是三个字的,前三个加入,后一个单字加入
addSegWord(strChar3,6);
strChar2[0] = strChar[6];strChar2[1] = strChar[7];
strChar2[2] = '\0';
addSegWord(strChar2,2);
i -= j ;
break;
}// 前三字不是词
}
}
else if ( 6 == j )
{ /*判断3个汉字,两种情况: 1+2 和 2+1,1+2止面8==j的地方已经捕获岐义,1+2好像不会有岐义
1+2 情况不要拆开
但以下地名如何处理:北京市房产公司,按理“北京”和“北京市“应该找到相同的,就是说,要能智能识别成"北京”和“北京市”是一样的*/
}
else if ( 2 == j )
{ //单个汉字
addSegWord(strChar,2);
i -= 2 ;
break;
}
bFound = searchWord(strChar , l );//in_array($strChar , $arrayChineseDict );//匹配词典
if ( TRUE == bFound )
{
i -= j;
addSegWord(strChar,l);
break;
}
else
{
//1.是否全是外来词
//2.是否全是数字
//3.如果第一二字是”姓氏“,则默认为姓名
//4.判断其它名字
}
} // end for j
} // end while $i > 0
return 0;
}
int initSegList()
{
int i , j ;
for ( i = 0 ; i < MAX_CDIM ; i ++ )
{
for ( j = 0 ; j < MAX_CDIM ; j ++ )
{
SEG_LIST[i][j].lstWord = (SEG_NODE *)NULL;
}
}
return TRUE;
}
int loadDict(char *strFilename)
{
int len = 0 , i ,j ;
FILE *fpDict = NULL;
unsigned char firstChar,lastChar;
// firstChar="a" ;
// lastChar='\0';
char sLine[128];
for ( i = 0 ; i < MAX_CDIM ; i ++ )
{
for ( j = 0 ; j < MAX_CDIM ; j ++ )
{
CH_DICT[i][j].lstWord = (WORD_NODE *)NULL;
}
}
fpDict = fopen(strFilename,"r");
if ( fpDict == ( FILE *)NULL )
{
printf("open dict file %s error !\n",strFilename);
return -1;
}
while ( !feof(fpDict))
{
fgets(sLine,128,fpDict);
strTrim(sLine);
len = strlen(sLine);
if ( len < 1 || len > MAX_CWORD_LEN )
printf("%s error!\n",sLine);
addDictWord(sLine,len);
}
fclose(fpDict);
return 0;
}
BOOL isEnglishStop(unsigned char *strWord)
{
//,arrayEnglishStop
return FALSE ;
}
/*inline*/ BOOL isAsciiSymbol(char cChar)
{
int i = 0 ;
for ( i = 0 ; i < sizeof(arrayAsciiSymbol) ; i ++ )
if ( cChar == arrayAsciiSymbol[i])
return TRUE;
return FALSE;
}
int segSentence (char *strText ,BOOL bSpace )
{
int iTextLen = strlen(strText) ;
int iWordLen= 0 ;
int i = 0 ;
int iNexti = 0 ;
BOOL bSep = FALSE ;//否是分隔符或者是一个词结束
BOOL bChinese = FALSE ;//上一个有效字符类型,
//false:英文 true: Chinese
BOOL bFound = FALSE ;
unsigned char strWord[MAX_SWORD_LEN + 1]; //当前词
unsigned char strChar[3]; //
unsigned char cChar; //
memset(strWord,0,sizeof(strWord));
strChar[0] = '\0';
for ( i = 0 ; i < iTextLen ; i ++ )
{
cChar = (unsigned char )strText[i];
if (128 > cChar) { //英文字符
/****如果连续空格不算分隔的话,用下面这一段代码 ****/
if ( ' ' == cChar || '\t' == cChar || '\r' == cChar || '\n' == cChar )
{
if ( TRUE == bChinese )
{ //如果前面一个有效字符是Chinese
if ( TRUE == bSpace && (' ' == cChar || '\t' == cChar))
bSep = TRUE ;
else continue ; //继续取下一个字符,因为汉字的词可以换行或用空格隔开
}
else
{
bSep = TRUE ;
}
}
else
{
bSep = isAsciiSymbol(cChar); //判断是否是分隔符
}
if ( (TRUE == bSep || TRUE == bChinese ) && 0 < iWordLen )
{ //一个单词结束
if ( iWordLen > MAX_SWORD_LEN )
iWordLen = MAX_SWORD_LEN;
strWord[iWordLen] = '\0';
segWord(strWord,iWordLen,bChinese);
iWordLen = 0 ;
}
if ( FALSE == bSep )
{
strWord[iWordLen] = cChar;
//同一个单词的字母,并在一起
iWordLen ++ ;
}
bChinese = FALSE ;
}
else
{ //字符Chinese
if ( FALSE == bChinese && FALSE == bSep && 0 < iWordLen )
{//以前是英文,碰到汉字,就当英文单词结束
if ( iWordLen > MAX_SWORD_LEN )
iWordLen = MAX_SWORD_LEN;
strWord[iWordLen] = '\0';
bFound = isEnglishStop(strWord);
if ( FALSE == bFound )
{
segWord(strWord,iWordLen,bChinese);
} // end if
iWordLen = 0 ;
}
iNexti = i + 1 ;
if ( iNexti < iTextLen )
{
if ( 128 > ((unsigned char)strText[iNexti]) )
{ //单字符>=128,不处理该字符
continue ;
}
}
else
{ //最后一个字符是大于128的单字符
break;
}
strChar[0] = strText[i];
strChar[1] = strText[i+1];
strChar[2] = '\0';
//是否有可能>128的字符,只有一个字符,如果有需要另外判断,现在默认一定会有至少两个字符同时出现
bChinese = TRUE ; //是汉字Chinese
i ++ ; //只需要加1
if (strChar[0] == 0xa1 && strChar[1] == 0xa1 )
{ //Chinese空格,16进制:A1,A1
if ( TRUE == bSpace )
bSep = TRUE ;
else continue ; //连续Chinese空格
}
else if ( strChar[0] < 176 )
{//中文标点等非汉字字符
bSep = TRUE ;
}
else bSep = FALSE;
if ( TRUE == bSep && 0 < iWordLen )
{
if ( iWordLen > MAX_SWORD_LEN )
iWordLen = MAX_SWORD_LEN;
strWord[iWordLen] = '\0';
segWord(strWord,iWordLen,bChinese);
iWordLen = 0 ;
}
if ( FALSE == bSep )
{
strWord[iWordLen++] = strChar[0];
strWord[iWordLen++] = strChar[1];
}
} // end if ord
} // end for $i
if ( 0 < iWordLen )
{ //还有未处理的单词
if ( iWordLen > MAX_SWORD_LEN )
iWordLen = MAX_SWORD_LEN;
strWord[iWordLen] = '\0';
segWord(strWord,iWordLen,bChinese);
iWordLen = 0 ;
}
return 0;
}
int main(int argc,char *argv[])
{
char strText[] = "遗传算法(Genetic Algorithm)是一类借鉴生物界的进化规律(适者生存,优胜劣汰遗传机制)演化而来的随机化搜索方法。遗传算法是模拟达尔文的遗传选择和自然淘汰的生物进化过程的计算模型。它的思想源于生物遗传学和适者生存的自然规律,是具有“生存+检测”的迭代过程的搜索算法。遗传算法以一种群体中的所有个体为对象,并利用随机化技术指导对一个被编码的参数空间进行高效搜索。其中,选择、交叉和变异构成了遗传算法的遗传操作;参数编码、初始群体的设定、适应度函数的设计、遗传操作设计、控制参数设定五个要素组成了遗传算法的核心内容。 作为一种新的全局优化搜索算法,遗传算法以其简单通用、鲁棒性强、适于并行处理以及高效、实用等显著特点,在各个领域得到了广泛应用,取得了良好效果,并逐渐成为重要的智能算法之一。";
loadDict("sqlet.dict");
initSegList();
printf("开始分词\n");
segSentence(strText ,TRUE ) ;
freeSeg();
printf("结束分词\n");
freeDict();
return 0 ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -