📄 stdafx.cpp
字号:
/*-----------------------------中文分词程序------------------------------
------------------------计算机系03级 03281047 刘川----------------------*/
// stdafx.cpp : source file that includes just the standard includes
// wordppl.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
#include <stdio.h>
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
extern char tt[][40];
char * source,* result; //文件暂存数组
int sum; //字典长度
FILE *fp1,*fp2; //定义两个文件指针
long filelen; //输入文件的长度
char scrbuf[MD]; //屏幕文件缓冲区
char scrres[SD]; //屏幕文件结果区
/*------------------------------------分词实现部分-----------------------------------------*/
//比较函数
int compare(const void* a,const void* b){
return strcmp((char*)a,(char*)b);
}
//折半查找算法
int binsearch(int Len,char *aidkey)
{ int low,high,mid;
low=0;high=Len-1;
while(low<=high)
{
mid=(low+high)/2;
if(strcmp(aidkey,tt[mid])==0)
return mid; //查找成功
else if(strcmp(tt[mid],aidkey)>0)
high=mid-1; //修改查找区间上界
else
low=mid+1; //修改查找区间下界
}
return -1; //查找失败
}
//初始化函数
int initialize()
{
sum=53335;
qsort(tt,sum,40*sizeof(char),compare); //对字典进行排序
return 1;
}
//屏幕分词函数,采用正向最大匹配算法
void scrposcutword()
{
int i,j,k; //普通变量
int end; //为1标示已经扫描完待分析文件,反之为0
int mask=0; //遇到不能识别字符则标记为1,否则为0
int bp,sb,rp; //bp为字符串已识别指针,sb为临时用指针,sp为结果数组指针
char ch[2],buffer[37];
filelen=strlen(scrbuf);
strcpy(scrres,"");
//分词主程序部分,采用正向最大匹配算法
bp=0;rp=0;
while(1)
{ buffer[0]=0;
sb=bp;
for(i=0;i<36;i++) //从源数组中读入36个字符
{
if(sb==filelen&&i==0) { end=1; break; } //读到的第一个字符为文件尾,于是退出
if(sb==filelen) //遇到文件尾,跳出循环
break;
ch[1]=0;
ch[0]=scrbuf[sb];
strcat(buffer,ch);
sb++;
}
if(end==1)break;
for(i=i-1;i>=0;i--)
{
k=strlen(buffer);
j=-1;
if( strcmp(buffer,"0")==0||strcmp(buffer,"1")==0||strcmp(buffer,"2")==0||strcmp(buffer,"3")==0||strcmp(buffer,"4")==0||
strcmp(buffer,"5")==0||strcmp(buffer,"6")==0||strcmp(buffer,"8")==0||strcmp(buffer,"7")==0||strcmp(buffer,"9")==0)
goto A;
j=binsearch(sum,buffer);
if(j!=-1) //如果查找到,则输出查找到的内容,并将bp指针往前移相应位置
{ if(mask==1) { mask=0; scrres[rp]='|'; rp++; scrres[rp]=0; }
strcat(scrres,buffer); rp+=k;
scrres[rp]='|'; rp++; scrres[rp]=0;
bp=bp+k;
break;
}
else //如果查不到
{
A: if(i==1) //若还剩2个字节,则判断第一个字节,若大于0,说明不是汉字,输出一个字节
{ buffer[2]=0; //若小于0,说明该汉字不在此库中,输出该字。并将bp指针往前移相应位置
if(buffer[0]<0)
{ strcat(scrres,buffer); rp+=2; scrres[rp]=0; bp=bp+2; mask=1; break;}
else
{ buffer[1]=0;
strcat(scrres,buffer); rp+=1; scrres[rp]=0; bp=bp+1; mask=1; break;
}
}
if(i==0) //若还剩1个字节,说明肯定是不能识别字符,则直接输出这个字节,并将bp指针往前移1个字节
{ buffer[1]=0;
strcat(scrres,buffer); rp++; scrres[rp]=0; bp=bp+1; mask=1; break;
}
buffer[i]=0; //将buffer最后一位去掉,再进行匹配
}
}//for(i=i-1;i>=0;i--)
}//while(1)
scrres[rp]=0;
}
//屏幕分词函数,采用逆向最大匹配算法
void scrnegcutword()
{
int i,j,k; //普通变量
// int end; //为1标示已经扫描完待分析文件,反之为0
int mask=0; //遇到不能识别字符则标记为1,否则为0
int bp,sb,rp; //bp为字符串已识别指针,sb为临时用指针,sp为结果数组指针
char buffer[37];
filelen=strlen(scrbuf);
for(i=0;i<2*filelen;i++)
{ scrres[i]=1; }
//分词主程序部分,采用正向最大匹配算法
bp=filelen-1;rp=2*filelen-1; scrres[rp+1]=0;
while(1)
{
if(bp<=35)
{ for(j=0;j<=bp;j++)
buffer[j]=scrbuf[j];
buffer[bp+1]=0;
}
else
{ sb=bp;
for(j=0;j<36;j++)
{ buffer[j]=scrbuf[sb-35+j]; }
buffer[j]=0;
}
if(bp==-1)break;
k=strlen(buffer);
for(i=k-1;i>=0;i--)
{
k=strlen(buffer);
j=-1;
if( strcmp(buffer,"0")==0||strcmp(buffer,"1")==0||strcmp(buffer,"2")==0||strcmp(buffer,"3")==0||strcmp(buffer,"4")==0||
strcmp(buffer,"5")==0||strcmp(buffer,"6")==0||strcmp(buffer,"8")==0||strcmp(buffer,"7")==0||strcmp(buffer,"9")==0)
goto A;
j=binsearch(sum,buffer);
if(j!=-1) //如果查找到,则输出查找到的内容,并将bp指针往后移相应位置
{ if(mask==1) { mask=0; scrres[rp]='|'; rp--; }
//strcat(scrres,buffer); rp-=k;
//k=strlen(buffer);
for(j=k-1;j>=0;j--)
{ scrres[rp]=buffer[j];
rp--;
}
scrres[rp]='|'; rp--;
bp=bp-k;
break;
}
else //如果查不到
{
A: if(i==1) //若还剩2个字节,则判断第一个字节,若大于0,说明不是汉字,输出一个字节
{ buffer[2]=0; //若小于0,说明该汉字不在此库中,输出该字。并将bp指针往后移相应位置
if(buffer[1]<0)
{ scrres[rp]=buffer[1];rp--;scrres[rp]=buffer[0]; rp--; bp=bp-2; mask=1; break; }
else
{ scrres[rp]=buffer[1]; rp-=1; bp=bp-1; mask=1; break;
}
}
if(i==0) //若还剩1个字节,说明是不能识别字符,则直接输出这个字节,并将bp指针往后移1个字节
{ buffer[1]=0;
scrres[rp]=buffer[0]; rp-=1; bp=bp-1; mask=1; break;
}
k=strlen(buffer);
for(j=0;j<k;j++) { buffer[j]=buffer[j+1]; } //将buffer第一位去掉,再进行匹配
}
}//for(i=i-1;i>=0;i--)
}//while(1)
for(i=0;i<2*filelen;i++)
if(scrres[i]!=1)
break;
for(j=0;j<2*filelen-i;j++)
{ scrres[j]=scrres[i+j]; }
scrres[j]=0;
}
//正向文件分词初始化函数
int preposcutword()
{
int i,j;
char c;
i = fseek(fp1,0,SEEK_END); //确定待分析文件的长度,用ftell函数
filelen = ftell( fp1 );
rewind(fp1); //计算回车的个数,因为文件操作时回车只算一个字符,而之前的统计认为回车是2个字符
j=0; //所以要减去回车的次数
while(1)
{ c=fgetc(fp1);
if(c==10) j++;
if(c==EOF) break;
}
filelen-=j;
source = (char *)malloc( filelen*sizeof(char) ); //动态为待分析文件分配内存
if( source == NULL ) //如果内存分配失败,则返回
return 0;
// { MessageBox(hWnd,"内存分配失败!","错误",MB_OK); }
rewind(fp1); //将文件指针定位在文件开始处
j=fread(source,1,filelen,fp1); //将待分析文件读入到source中
return 1;
}
//文件分词函数,采用正向最大匹配算法
void poscutword()
{
int i,j,k; //普通变量
int end; //为1标示已经扫描完待分析文件,反之为0
int mask; //遇到不能识别字符则标记为1,否则为0
int bp,sb; //bp为字符串已识别指针,sb为临时用指针
char ch[2],buffer[37];
bp=0;
while(1)
{ buffer[0]=0;
sb=bp;
for(i=0;i<37;i++) //从source中读入37个字符
{
if(sb==filelen&&i==0) { end=1; break; } //读到的第一个字符为文件尾,于是退出
if(sb==filelen) //遇到文件尾,跳出循环
break;
ch[1]=0;
ch[0]=source[sb];
strcat(buffer,ch);
sb++;
}
if(end==1)break;
for(i=i-1;i>=0;i--)
{
k=strlen(buffer);
j=-1;
j=binsearch(sum,buffer);
if(j!=-1) //如果查找到,则输出查找到的内容,并将bp指针往前移相应位置
{ if(mask==1) { mask=0; fprintf(fp2,"|"); }
fprintf(fp2,"%s",buffer);
fprintf(fp2,"|");
bp=bp+k;
break;
}
else //如果查不到
{
if(i==1) //若还剩2个字节,则判断第一个字节,若大于0,说明不是汉字,输出一个字节
{ buffer[2]=0; //若小于0,说明该汉字不在此库中,输出该字。并将bp指针往前移相应位置
if(buffer[0]<0)
{ fprintf(fp2,"%s",buffer); bp=bp+2; mask=1; break;}
else
{ buffer[1]=0;
fprintf(fp2,"%s",buffer); bp=bp+1; mask=1; break;
}
}
if(i==0) //若还剩1个字节,说明肯定是不能识别字符,则直接输出这个字节,并将bp指针往前移1个字节
{ buffer[1]=0;
fprintf(fp2,"%s",buffer); bp=bp+1; mask=1; break;
}
buffer[i]=0; //将buffer最后一位去掉,再进行匹配
}
}//for(i=i-1;i>=0;i--)
}//while(1)
free(source);
}
//逆向文件分词初始化函数
int prenegcutword()
{
int i,j;
char c;
i = fseek(fp1,0,SEEK_END); //确定待分析文件的长度,用ftell函数
filelen = ftell( fp1 );
rewind(fp1); //计算回车的个数,因为文件操作时回车只算一个字符,而之前的统计认为回车是2个字符
j=0; //所以要减去回车的次数
while(1)
{ c=fgetc(fp1);
if(c==10) j++;
if(c==EOF) break;
}
filelen-=j;
source = (char *)malloc( filelen*sizeof(char) ); //动态为待分析文件分配内存
if( source == NULL ) //如果内存分配失败,则返回
return 0;
j=filelen*2;
result = (char *)malloc( j*sizeof(char)+1 ); //动态为待分析文件结果数组分配内存
if( result == NULL ) //如果内存分配失败,则返回
return 0;
for(i=0;i<2*filelen-1;i++)
{ result[i]=1; }
// { MessageBox(hWnd,"内存分配失败!","错误",MB_OK); }
rewind(fp1); //将文件指针定位在文件开始处
j=fread(source,1,filelen,fp1); //将待分析文件读入到source中
return 1;
}
//文件分词函数,采用逆向最大匹配算法
void negcutword()
{
int i,j,k; //普通变量
int mask=0; //遇到不能识别字符则标记为1,否则为0
int bp,sb,rp; //bp为字符串已识别指针,sb为临时用指针,sp为结果数组指针
char buffer[37];
//分词主程序部分
bp=filelen-1;rp=2*filelen-1; result[rp+1]=0;
while(1)
{
if(bp<=35)
{ for(j=0;j<=bp;j++)
buffer[j]=source[j];
buffer[bp+1]=0;
}
else
{ sb=bp;
for(j=0;j<36;j++)
{ buffer[j]=source[sb-35+j]; }
buffer[j]=0;
}
if(bp==-1)break;
k=strlen(buffer);
for(i=k-1;i>=0;i--)
{
k=strlen(buffer);
j=-1;
if( strcmp(buffer,"0")==0||strcmp(buffer,"1")==0||strcmp(buffer,"2")==0||strcmp(buffer,"3")==0||strcmp(buffer,"4")==0||
strcmp(buffer,"5")==0||strcmp(buffer,"6")==0||strcmp(buffer,"8")==0||strcmp(buffer,"7")==0||strcmp(buffer,"9")==0)
goto A;
j=binsearch(sum,buffer);
if(j!=-1) //如果查找到,则输出查找到的内容,并将bp指针往后移相应位置
{ if(mask==1) { mask=0; result[rp]='|'; rp--; }
for(j=k-1;j>=0;j--)
{ result[rp]=buffer[j];
rp--;
}
result[rp]='|'; rp--;
bp=bp-k;
break;
}
else //如果查不到
{
A: if(i==1) //若还剩2个字节,则判断第一个字节,若大于0,说明不是汉字,输出一个字节
{ buffer[2]=0; //若小于0,说明该汉字不在此库中,输出该字。并将bp指针往后移相应位置
if(buffer[1]<0)
{ result[rp]=buffer[1];rp--;result[rp]=buffer[0]; rp--; bp=bp-2; mask=1; break; }
else
{ result[rp]=buffer[1]; rp-=1; bp=bp-1; mask=1; break;
}
}
if(i==0) //若还剩1个字节,说明是不能识别字符,则直接输出这个字节,并将bp指针往后移1个字节
{ buffer[1]=0;
result[rp]=buffer[0]; rp-=1; bp=bp-1; mask=1; break;
}
k=strlen(buffer);
for(j=0;j<k;j++) { buffer[j]=buffer[j+1]; } //将buffer第一位去掉,再进行匹配
}
}//for(i=i-1;i>=0;i--)
}//while(1)*/
for(i=0;i<2*filelen;i++)
if(result[i]!=1)
break;
for(j=0;j<2*filelen-i;j++)
{ result[j]=result[i+j]; }
result[j]=0;
j=strlen(result);
fwrite(result,1,j,fp2);
for(i=0;i<2*filelen-1;i++)
{ result[i]=1; }
free(result);
free(source);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -