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

📄 5 创建向量模型.cpp

📁 1998年1月份人民日报语料中体育类文章的识别
💻 CPP
字号:
//功能:根据语料生成字典
//输入:dic_try3.txt  词/词性序列
//

#include <stdio.h>
#include <math.h>
//词条,用于记录某个字打头的词组
struct ct{ 
		unsigned char cc[30];
		int freq;
		ct *next;
		double ym_cx[44];
		double length;
	};
//词头,每个字对应一个词头,词头引领词条
struct ctou{ 
		ct *head;
		ct *tail;
		int count;
	} ctou[8000];

#define sen_len 150   

//全局变量
int in_dic[sen_len][16];		//用于存储词图
struct ct *in_dic_pos [sen_len][16];

unsigned char test[sen_len]="\0";


FILE *fp_cx;		

int compare(unsigned char *dic_ct,int length1,unsigned char *a ,int length2);//比较两个字符串是否相等
void strcopy(unsigned char *dic_ct,unsigned char *a,int length );			 //把一个字符数组的内容拷贝到另一个数组
void fputstr(unsigned char * a,int length,FILE * pfw);						 //将字符串内容写入文件,可用 fprintf 代替
int array_len(unsigned char *c);											 //判断字符数组的实际长度
void sen_read(FILE *fp,unsigned char *c);									 //读入一个句子?
int ym_create(char * str);
int xl_compute(char * str);																 //构建隐马模型	
void print_dic();//将字典中的所有词条打印到keyword.txt文本
void clear_dic();//将字典中的说哟词条freq项清0

void main()
{
//1创建模型-------------------------------------------
ym_create("dic_try3.txt");
//测试用:显示字典内容

clear_dic();
//ym_create("doc.txt");

xl_compute("doc.txt");
print_dic();
}
//---------------------------------------------------//---------------------------------------------------

void fputstr(unsigned char * a,int length,FILE * pfw)
{	
	for(int i=0;i<length*2;i++)
	{	
		fputc(a[i],pfw);
	}
	fputc(' ',pfw);
}


void strcopy(unsigned char *dic_ct,unsigned char *a ,int length)
{
	for (int i=0;i<length;i++)
		dic_ct[i]=a[i];
	dic_ct[i]='\0';
}

int compare(unsigned char *dic_ct,int length1,unsigned char *a ,int length2)
{
	if(length1!=length2/2)return 1;	//判断词等长	
	for (int i=0;i<length2;i++)		//判断词中每个字节都相等
		if(dic_ct[i]!=a[i]){return 1;}
		return 0;					//两词相等返回0
}
//返回数组长度(不含/0)
int array_len(unsigned char *c)
{	
	int i=0;
	while(c[i]!='\0')	
	{i++;}
	return i;
	
}
//---------------------------------------------------cut
void sen_read(FILE *fp,unsigned char *c)
{
unsigned char getc;
int i=0;
getc=fgetc(fp);
while(getc!=255)
{
	c[i]=getc;
	i++;
	getc=fgetc(fp);
}
c[i]='\0';
}


void print_dic()
{
	FILE *fpw;
	fpw=fopen("keyword.txt","w");//写入文件
	
	int i=0;
	for(i=0;i<8000;i++)
	{
		ct *head=ctou[i].head;
		while(head!=NULL)
		{	
		fprintf(fpw,"%s  %d\n",head->cc,head->freq);	
	//	printf("%s\n",head->cc);	
		head=head->next;
		}	
	}
}

void clear_dic()
{	
	int i=0;
	for(i=0;i<8000;i++)
	{
		ct *head=ctou[i].head;
		while(head!=NULL)
		{	
			head->freq=0;
			head=head->next;
		}	
	}





}






//------------------------------------------------------

int ym_create(char * str)
{
	unsigned char a[60];//30字符,15词;
	FILE *fp;
	fp=fopen(str,"r");//读入文件,用于创建字典的语料库文件
	if (fp==NULL)
	{	printf("cannot open thi file\n");}

//对 词头结构 进行初始化	
	for (int j=0;j<8000;j++)
		{
			ctou[j].head=NULL;	
			ctou[j].tail=NULL;
		    ctou[j].count=0;
		}	





//循环处理,字典构建开始
	unsigned char c1;	int i=0;int temp=0;//用于处理读取词性的结果
	while(!feof(fp))
	{
		int flag_c_cx=0;//处理词,词性标志位;
		int writeddown=0;i=0;		
		
		for(j=0;j<60;j++) 
			a[j]=0;

//取token:同时读取词性(读取词 到a[],读取词性 到temp )
		do{		//如果不是空格 读入字符到数组.
			c1 =fgetc(fp);	//读入一位
			if(c1==255){break;}//如果是文章结尾则跳出

	//1 根据 '/' 和 ' '修改 当前状态(1 词性 0 词 )
			if(c1=='/')
			{
				flag_c_cx=1;continue;//转为处理词性状态
			}
			if(c1==32 && flag_c_cx==1)
			{
				flag_c_cx=0;//结束处理词性状态,转为处理词状态
			}

	//2 处理词性部分;			
			if(flag_c_cx==1)//处理词性部分;
			{
				unsigned char c2=fgetc(fp);//取下一词
				if(c2==' ' || c2==255)
				{			//本字符是单字符
					temp=c1-97; 						
					c1=c2; 	flag_c_cx=0;
					continue;
				}
				else{//本字符是双字符
					temp=c2+c1;		
				switch(temp)
				{
				case 168:	temp=26;break;//Ag	
				case 169:	temp=27;break;//Bg(s)------------存在问题
				case 171:	temp=28;break;//Dg
				case 180:	temp=29;break;//180  Mg		(s)	
				case 181:	temp=30;break;//Ng
				case 185:	temp=31;break;//Rg(s)
				case 187:	temp=32;break;//Tg
				case 189:   temp=33;break;//Vg		
				case 192:	temp=34;break;//192 Yg(只出现过一次:耳)	
				case 197:	temp=35;break;//ad
				case 207:   temp=36;break;//an	
				case 218:	temp=37;break;//vd
				case 224:	temp=38;break;//nv
				case 225:	temp=39;break;//ns
				case 226:	temp=40;break;//nt
				case 228:	temp=41;break;//vn
				case 230:   temp=42;break;//nx
				case 232:	temp=43;break;//nz
				}	
				c1=c2;	flag_c_cx=0;continue;
				}			
			}//end-if
	//3处理空格
			if(c1==32){continue;}

			a[i]=c1;writeddown=1;i++;			/*	*/	
		}while(c1!=32||writeddown==0);//如果是token前的空格,循环;	

		if(c1==-1){printf("end-here");break;}
		a[i]='\0';
	//测试用:显示取词结果	
		if(i>30)//词长超过15不予处理
		{//printf("%s:%d\n",a,temp);
		continue;}		

	//4写入字典(词和词性都已经处理完毕)
		//4.1计算地址
		if(a[0]<0xa1 && a[0]>0xf7){printf("超出处理范围错误\n");continue;}
		if(i>0)//字符数组内容不为空,即词存在
		{
				int s1=0;
				if(a[0]>=0xb0)
				{
					s1=(a[0]-0xb0)*96+(a[1]-0xa0);if(s1>6920||s1<0)printf("创建字典错误");	
				}
				if(a[0]<0xb0 && a[0]>=0xa1)
				{  // continue;
					s1=(a[0]-0xa1)*96+(a[1]-0xa0)+7000;
					if(s1>8000||s1<0){printf("创建字典标点-错误\n");printf("%d\n",s1);}
				}
		//	printf("%s:%d\t",a,temp);
		//4.2判断词是否已经在节点中,这部分作为字典导入内存用可以直接删除

				ct *head=ctou[s1].head;
				while(head!=NULL)
				{	
					if(compare(head->cc,head->length,a,i)==0)//两词相等
					{head->freq++;head->ym_cx[temp]++;break;}						
					head=head->next;
				}	
		//4.3将新词写入字典		
				if(head==NULL)//如果词条为空,新建词条,将词条写入
				{	
					struct ct *p=new ct();
					p->freq=1;
					for(int j=0;j<44;j++)
						p->ym_cx[j]=0;
					strcopy(p->cc,a,i);			
					p->next=NULL;
					p->length=i/2;
					if(ctou[s1].count==0)
					{
						ctou[s1].head=p;
						ctou[s1].tail=p;
					}
					else{ctou[s1].tail->next=p;ctou[s1].tail=p;}				
					ctou[s1].count++;
				}
		}
	//4-end 写入词典结束
	} //循环结束,字典构建结束。

fclose(fp);

	 
	 return 1;
}

//------------------------------------------------------
int xl_compute(char * str)
{
	unsigned char a[60];//30字符,15词;
	FILE *fp;
	fp=fopen(str,"r");//读入文件,用于创建字典的语料库文件
	if (fp==NULL)
	{	printf("cannot open thi file\n");}

//循环处理,字典构建开始
	unsigned char c1;	int i=0;int temp=0;//用于处理读取词性的结果
	while(!feof(fp))
	{
		int flag_c_cx=0;//处理词,词性标志位;
		int writeddown=0;i=0;		
		int j=0;
		for(j=0;j<60;j++) 
			a[j]=0;

//取token:同时读取词性(读取词 到a[],读取词性 到temp )
		do{		//如果不是空格 读入字符到数组.
			c1 =fgetc(fp);	//读入一位
			if(c1==255){break;}//如果是文章结尾则跳出

	//1 根据 '/' 和 ' '修改 当前状态(1 词性 0 词 )
			if(c1=='/')
			{
				flag_c_cx=1;continue;//转为处理词性状态
			}
			if(c1==32 && flag_c_cx==1)
			{
				flag_c_cx=0;//结束处理词性状态,转为处理词状态
			}

	//2 处理词性部分;			
			if(flag_c_cx==1)//处理词性部分;
			{
				unsigned char c2=fgetc(fp);//取下一词
				if(c2==' ' || c2==255)
				{			//本字符是单字符
					temp=c1-97; 						
					c1=c2; 	flag_c_cx=0;
					continue;
				}
				else{//本字符是双字符
					temp=c2+c1;		
				switch(temp)
				{
				case 168:	temp=26;break;//Ag	
				case 169:	temp=27;break;//Bg(s)------------存在问题
				case 171:	temp=28;break;//Dg
				case 180:	temp=29;break;//180  Mg		(s)	
				case 181:	temp=30;break;//Ng
				case 185:	temp=31;break;//Rg(s)
				case 187:	temp=32;break;//Tg
				case 189:   temp=33;break;//Vg		
				case 192:	temp=34;break;//192 Yg(只出现过一次:耳)	
				case 197:	temp=35;break;//ad
				case 207:   temp=36;break;//an	
				case 218:	temp=37;break;//vd
				case 224:	temp=38;break;//nv
				case 225:	temp=39;break;//ns
				case 226:	temp=40;break;//nt
				case 228:	temp=41;break;//vn
				case 230:   temp=42;break;//nx
				case 232:	temp=43;break;//nz
				}	
				c1=c2;	flag_c_cx=0;continue;
				}			
			}//end-if
	//3处理空格
			if(c1==32){continue;}

			a[i]=c1;writeddown=1;i++;			/*	*/	
		}while(c1!=32||writeddown==0);//如果是token前的空格,循环;	

		if(c1==-1){printf("end-here");break;}
		a[i]='\0';
	

	//4写入字典(词和词性都已经处理完毕)
		//4.1计算地址
		if(a[0]<0xa1 && a[0]>0xf7){printf("超出处理范围错误\n");continue;}
		if(i>0)//字符数组内容不为空,即词存在
		{
				int s1=0;
				if(a[0]>=0xb0)
				{
					s1=(a[0]-0xb0)*96+(a[1]-0xa0);if(s1>6920||s1<0)printf("创建字典错误");	
				}
				if(a[0]<0xb0 && a[0]>=0xa1)
				{  
					s1=(a[0]-0xa1)*96+(a[1]-0xa0)+7000;
					if(s1>8000||s1<0){printf("创建字典标点-错误\n");printf("%d\n",s1);}
				}
		//4.2判断词是否已经在节点中
				ct *head=ctou[s1].head;
				while(head!=NULL)
				{	
					if(compare(head->cc,head->length,a,i)==0)//两词相等
					{head->freq++;head->ym_cx[temp]++;break;}						
					head=head->next;
				}	

		}
	//4-end 写入词典结束
	} //循环结束,字典构建结束。

fclose(fp);

	 
	 return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -