📄 oncorpusnew.cpp
字号:
//创建语料库
void CMainFrame::OnCorpusNew()
{
CFileDialog dlg(FALSE); //获取语料存盘文件名
if(dl.DoModel()!=IDOK) return;
if(1 corpusName.IsEmpty()) OnCorpusClose(); //关闭当前语料库
corpusName = dlg.GetPathName();
OnCorpusAdd(); //添加语料
}
//打开语料库
void CMainFrame::OnCorpusOpen()
{
CFileDialog dlg(TRUE,"ylk","*.ylk",
OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT,
"语料库文件|*.ylk|所有文件||"); //语料库存盘文件
if(dl.DoModel()!=IDOK) return;
if(1 corpusName.IsEmpty()) OnCorpusClose();
CFile cf;char buf[512];
if(cf.Open(const char *)(dlg.GetPathName()),CFile::modeRead){
CArchive ar(&cf, CArchive::load,512,buf);
texts.Serialize(ar);// 读入所有语料文件名
}
else {AfxMessageBox("无法打开语料库!");return;}
CFile tf;
CString ylkName = ChangeExt(dlg.GetPathName(), "@@@");
if(tf.Open(const char *)ylkName,CFile::modeRead)){
CArchive ar(&tf, CArchive::load,512,buf);
for(int i=0;i<6768;i++)
hzInfo[i].Serialize(ar); //读入每个汉字的信息(出现次数和地址串)
}
else{AfxMessageBox("无法读入汉字信息!");return;}
corpusName = dlg.GetPathName(); //保存语料库文件名
CorpusModified=FALSE; //语料库修改标记
}
//关闭语料库
void CMainFrame::OnCorpusClose()
{
if(corpusName.IsEmpty()) return;
if(CorpusModified) { //如果语料库已经修改
CFile cf;char buf[512];
if(cf.Open((const char *)corpusName,
CFile::modeCreate|CFile::modeWrite)){
CArchive ar(&cf, CArchive::store,512,buf);
texts.Serialize(ar);
}
else {AfxMessageBox("语料库无法存盘!");return;}
texts.RemoveAll();
CFile tf;
CString ylkName = ChangeExt(corpusName, "@@@");
if(tf.Open(const char *)ylkName,
CFile::modeCreate|CFile::modeWrite)){
CArchive ar(&tf, CArchive::store,512,buf);
for(int i=0;i<6768;i++)
hzInfo[i].Serialize(ar);
}
else{AfxMessageBox("汉字信息无法存盘!");return;}
corpusName = ""; //表示现在没有打开的语料库
CorpusModified=FALSE; //语料库修改标记
}
//增加语料
void CMainFrame::OnCorpusAdd()
{
if(corpusName.IsEmpty()||texts.GetSize() == 65535) return;
ProcessFiles ("txt","*.txt",AddAFile);
}
void AddAFile(CString FileName)
{
int n= texts.GetSize();
if( n == 65535) return;
FILE *in; in=fopen((const char *)FileName, "rb");
if(!in) {AfxMessageBox("打不开文件!"+ FileName);return;}
while (! feof(in)) {
unsigned char c1,c2;
c1=(unsigned cahr)fgetc(in);
if(c1<128) continue; //不处理西文字符
c1=(unsigned cahr)fgetc(in);
if(c1>=176) { //如果是汉字
int id =HZ_ID(c1,c2); if(id<0||id>=6768) continue;
hzInfo[id].AddTextID(n); //将语料文件序号加入地址串
}
}
fclose(in);
FileName.MakeLower(); //将文件名中的字母转为小写
texts.Add(FileName); //将文件名添加到字符串数组
CorpusModified = TRUE; //设置语料库修改标记
}
//检索汉字串
//需要获取用户输入待查找的汉字串,并检查其合法性
void CMainFrame::OnCorpusHanzi()
{
CString key;
if(!GetData("查找汉字串:",key)) return;
key.TrimLeft(); key.TrimRight(); //压缩前后空格
int id,id2, n=key.GetLength();
if(! GoodHzStr(key)) { //检查输入的合法性
AfxMessageBox("输入的汉字串有错误!"+ FileName);
return;
}
CWordArray *txtID, *tmp;
id=HZ_ID((unsigned char)key[0],(unsigned char)key[1]);
if(n==2){ //如果输入的是单个汉字
txtID=& (hzInfo[id].TextID);
if(txtID->GetSize()==0) {
AfxMessageBox("找不到这个汉字串");
return;
}
Retrive(txtxID,key); //在语料文件中检索汉字key
return;
}
//以下处理检索多个汉字
id2 =HZ_ID((unsigned char)hey[2],(unsigned char)hey[3]);
//第二个汉字
txtID = Intersection(hzInfo[id].TextID,hzInfo[id2].TextID);
//求前两个汉字的地址串的交集
int i=4; //从第三个汉字开始
while(txtID->GetSize()>0 && i<key.GetLength()-1){
id2 =HZ_ID((unsigned char)hey[i],(unsigned char)hey[i+1]);
tmp= Intersection(*textID,hzInfo[id2].TextID);
delete txtID;txtID=tmp;i+=2;
}
if(txtID->GetSize() == 0) { //如果交集为空
AfxMessageBox("找不到这个汉字串");
return;
}
Retrive(txtxID,key); //在语料文件中检索汉字key
return;
}
//合法性输入函数
BOOL GoodHzStr(CString s)
{
int n=s.GetLength();
if(n==0||n%2!=0) return FALSE;
for(int i=0;i<n-1:i+=2)
if((unsigned char)s[i]<176 || (unsigned char)s[i]<161) return FALSE;
return TRUE;
}
//求地址串的交集
CWordArray *Intersection(CWordArray &wi, CWordArray &wj)
{
CWordArray *pw= new CWordArray; //交集指针
for(int i=0,j=0; i<wi.GetSize() && j<wj.GetSize();) {
if(wi[i] == wj[j]) {
pw->Add(wi[i]); i++;j++;} //加入相同地址
else if(wi[i]<wj[j]) i++;
else j++;
}
return pw;
}
//由地址查找汉字串
void Retrive(CWordArray *txtID, CString key)
{
if(txtID->GetSize() == 0) return;
FILE *in, *out;
int Examples=0;
out = fopen("f:\\work\\4.8\\现代汉语自动分析\\output.txt","wt");
if(! out) { AfxMessageBox("无法创建检索输出文件!");return; }
CStdioFile outFile(out);
outFile.WriteString("查找字符串:“");
outFile.WriteString(key+"”\n");
for(int i=0;i<txtID->GetSize();i++){
int id = txtID->GetAt(i); //取出一个地址
CStdio fname = texts[id]; //取出相应的语料文件名
in=fopen((const char *)frame, "rt");
if(! in) { AfxMessageBox("找不到语料文件"+frame);continue; }
CStdioFile inFile(in);
char s[3000];CString ss="",dd;
while (inFile.ReadString(s,3000)) //读语料文件的每一行
if(key.GetLength()>2 && strstr(s,(const char *))key)
|| key.GetLength()== 2 && FindOneHZ(s,(const char *)key)>= 0) { //如果含有该汉字或者汉字串
Examples s++; //例子个数
dd.Format("例%40d:",Examples);
ss+ = dd + s ;ss+ = '\n'; //加到输出串中
}
if(ss.GetLength()>0) {
outFile.WriteString(fname+":\n"); //写文件名
outFile.WriteString(ss+"”\n"); //写输出串
}
inFile.Close();
}
outFile.Close();
if(Examples >0) AfxGetApp()-> OpenDocumentFile("output.txt");
//在应用程序中打开输出文件
else AfxMessageBox("找不到这个汉字串");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -