?? 4 創(chuàng)建詞典.cpp
字號:
//功能:根據(jù)語料生成字典
//輸入:dic_try3.txt 詞/詞性序列
//
#include <stdio.h>
#include <math.h>
//詞條,用于記錄某個字打頭的詞組
struct ct{
unsigned char cc[30];
double freq;
ct *next;
double ym_cx[44];
double length;
};
//詞頭,每個字對應(yīng)一個詞頭,詞頭引領(lǐng)詞條
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 ); //把一個字符數(shù)組的內(nèi)容拷貝到另一個數(shù)組
void fputstr(unsigned char * a,int length,FILE * pfw); //將字符串內(nèi)容寫入文件,可用 fprintf 代替
int array_len(unsigned char *c); //判斷字符數(shù)組的實際長度
void sen_read(FILE *fp,unsigned char *c); //讀入一個句子?
int ym_create(); //構(gòu)建隱馬模型
void print_dic();
void main()
{
//1創(chuàng)建模型-------------------------------------------
ym_create();
//測試用:顯示字典內(nèi)容
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++) //判斷詞中每個字節(jié)都相等
if(dic_ct[i]!=a[i]){return 1;}
return 0; //兩詞相等返回0
}
//返回數(shù)組長度(不含/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\n",head->cc);
// printf("%s\n",head->cc);
head=head->next;
}
}
}
//------------------------------------------------------
//隱馬模型創(chuàng)建:
//ym_B構(gòu)建
//構(gòu)建ym_pi,構(gòu)建ym_A。
int ym_create()
{//功能:創(chuàng)建隱馬模型中的表 :A,B,PI
unsigned char a[60];//30字符,15詞;
FILE *fp;
fp=fopen("dic_try3.txt","r");//讀入文件,用于創(chuàng)建字典的語料庫文件
if (fp==NULL)
{ printf("cannot open thi file\n");}
//對 詞頭結(jié)構(gòu) 進行初始化
for (int j=0;j<8000;j++)
{
ctou[j].head=NULL;
ctou[j].tail=NULL;
ctou[j].count=0;
}
//循環(huán)處理,字典構(gòu)建開始
unsigned char c1; int i=0;int temp=0;//用于處理讀取詞性的結(jié)果
while(!feof(fp))
{
int flag_c_cx=0;//處理詞,詞性標(biāo)志位;
int writeddown=0;i=0;
for(j=0;j<60;j++)
a[j]=0;
//取token:同時讀取詞性(讀取詞 到a[],讀取詞性 到temp )
do{ //如果不是空格 讀入字符到數(shù)組.
c1 =fgetc(fp); //讀入一位
if(c1==255){break;}//如果是文章結(jié)尾則跳出
//1 根據(jù) '/' 和 ' '修改 當(dāng)前狀態(tài)(1 詞性 0 詞 )
if(c1=='/')
{
flag_c_cx=1;continue;//轉(zhuǎn)為處理詞性狀態(tài)
}
if(c1==32 && flag_c_cx==1)
{
flag_c_cx=0;//結(jié)束處理詞性狀態(tài),轉(zhuǎn)為處理詞狀態(tài)
}
//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(只出現(xiàn)過一次:耳)
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前的空格,循環(huán);
if(c1==-1){printf("end-here");break;}
a[i]='\0';
//測試用:顯示取詞結(jié)果
if(i>30)//詞長超過15不予處理
{//printf("%s:%d\n",a,temp);
continue;}
//4寫入字典(詞和詞性都已經(jīng)處理完畢)
//4.1計算地址
if(a[0]<0xa1 && a[0]>0xf7){printf("超出處理范圍錯誤\n");continue;}
if(i>0)//字符數(shù)組內(nèi)容不為空,即詞存在
{
int s1=0;
if(a[0]>=0xb0)
{
s1=(a[0]-0xb0)*96+(a[1]-0xa0);if(s1>6920||s1<0)printf("創(chuàng)建字典錯誤");
}
if(a[0]<0xb0 && a[0]>=0xa1)
{ // continue;
s1=(a[0]-0xa1)*96+(a[1]-0xa0)+7000;
if(s1>8000||s1<0){printf("創(chuàng)建字典標(biāo)點-錯誤\n");printf("%d\n",s1);}
}
// printf("%s:%d\t",a,temp);
//4.2判斷詞是否已經(jīng)在節(jié)點中,這部分作為字典導(dǎo)入內(nèi)存用可以直接刪除
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=0;
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 寫入詞典結(jié)束
} //循環(huán)結(jié)束,字典構(gòu)建結(jié)束。
fclose(fp);
return 1;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -