⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stdafx.cpp

📁 本程序采用正向 逆向最大匹配才实现汉字分词
💻 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 + -