📄 mydictionary.cpp
字号:
#include "stdafx.h"
#include "MyDictionary.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// # define MaxWordLength 8 // 最大词长为8个字节(即4个汉字)
extern int MaxWordLength; // 最大词长由用户在.ini文件中指定
/////////////////////////////////////////////////////////////////////////////
// CWordTagSet
IMPLEMENT_DYNAMIC(CWordTagSet, CDaoRecordset)
CWordTagSet::CWordTagSet(CDaoDatabase* pdb)
: CDaoRecordset(pdb)
{
//{{AFX_FIELD_INIT(CWordTagSet)
m_wid = 0;
m_pos = _T("");
m_pfreq = 0;
m_pid = 0;
m_word = _T("");
m_wfreq = 0;
m_wid2 = 0;
m_nFields = 7;
//}}AFX_FIELD_INIT
m_nDefaultType = dbOpenSnapshot;
m_WordParam=""; // 给词语参数赋值
m_TagParam=""; // 给词性标记参数赋值
m_nParams = 2; // 参数个数为2
}
/*
CString CWordTagSet::GetDefaultDBName()
{
return _T("Lexicon.mdb");
}
CString CWordTagSet::GetDefaultSQL()
{
return _T("[poss],[words]");
}
*/
void CWordTagSet::DoFieldExchange(CDaoFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CWordTagSet)
pFX->SetFieldType(CDaoFieldExchange::param);
DFX_Text(pFX,"wordParam",m_WordParam);
DFX_Text(pFX,"tagParam",m_TagParam);
pFX->SetFieldType(CDaoFieldExchange::outputColumn);
DFX_Long(pFX, _T("[poss].[wid]"), m_wid);
DFX_Text(pFX, _T("[pos]"), m_pos);
DFX_Long(pFX, _T("[pfreq]"), m_pfreq);
DFX_Long(pFX, _T("[pid]"), m_pid);
DFX_Text(pFX, _T("[word]"), m_word);
DFX_Long(pFX, _T("[wfreq]"), m_wfreq);
DFX_Long(pFX, _T("[words].[wid]"), m_wid2);
//}}AFX_FIELD_MAP
}
/////////////////////////////////////////////////////////////////////////////
// CWordTagSet diagnostics
#ifdef _DEBUG
void CWordTagSet::AssertValid() const
{
CDaoRecordset::AssertValid();
}
void CWordTagSet::Dump(CDumpContext& dc) const
{
CDaoRecordset::Dump(dc);
}
#endif //_DEBUG
int CWordTagSet::GetFreq(CString w, CString t)
{
// 参量赋值
m_WordParam=w;
m_TagParam=t;
// 设置查询条件
m_strFilter="words.wid=poss.wid AND word=wordParam AND pos=tagParam";
// 执行查询
Requery();
if(GetRecordCount()==0)
return -1;
else
return m_pfreq; // 返回该词语在这一词性标记下的出现次数
}
int CWordTagSet::GetFreqs(CString w, CObArray &a)
{// 第二个参数是动态数组,存放查询到的标记及其出现次数
m_WordParam=w; // 只给一个参数变量赋值
m_strFilter="words.wid=poss.wid AND word=wordParam";
Requery();
if(GetRecordCount()==0)
return 0;
for(int i=0;i<a.GetSize();i++)
if (a[i])
delete a[i];
a.RemoveAll();
i=0;
CTagFreq * tf;
while(!IsEOF()) {
tf=new CTagFreq(m_pos,m_pfreq);
a.Add(tf);
i++;
MoveNext();
}
return i;
}
///////////////////////////////////////////////
///////////////////////////////////////////////
// CMyDictionary 类成员函数定义
BOOL CMyDictionary :: OpenMDB()
{//打开词语表,词性标记表
if (myDatabaseName.IsEmpty()) {
CFileDialog dlg(TRUE, "mdb", "*.mdb",OFN_OVERWRITEPROMPT);
if (dlg.DoModal()!=IDOK) {
AfxMessageBox("您没有打开词库");
return FALSE;
}
myDatabaseName = dlg.GetPathName();
}
if(pDatabase)
return FALSE;
pDatabase=new CDaoDatabase;
pDatabase->Open(myDatabaseName);
pWordsDef=new CDaoTableDef(pDatabase);
pWordsDef->Open("words"); // 打开词表结构,用词表名words作为参数
pWords=new CDaoRecordset(pDatabase);
pWords->Open(pWordsDef); // 打开词表记录集,用词表结构指针作为参数
pTagsDef=new CDaoTableDef(pDatabase);
pTagsDef->Open("poss"); // 打开词性表结构,用词性表名poss作为参数
pTags=new CDaoRecordset(pDatabase);
pTags->Open(pTagsDef); // 打开词性表记录集,用词性表结构指针作为参数
return TRUE;
}
BOOL CMyDictionary :: CloseMDB()
{// 构析函数,关闭词语表,词性标记表,中文姓名表
if(pWords) {
pWords->Close();
delete pWords;
}
if(pTags) {
pTags->Close();
delete pTags;
}
if(pWordsDef) {
pWordsDef->Close();
delete pWordsDef;
}
if(pTagsDef) {
pTagsDef->Close();
delete pTagsDef;
}
if(pDatabase) {
pDatabase->Close();
delete pDatabase;
AfxDaoTerm(); // can now safely terminate DAO
}
else
return FALSE;
myDatabaseName = "";
return TRUE;
}
long CMyDictionary :: GetWordID(CString w)
{
COleVariant kw(w,VT_BSTRT),kwi;
pWords->SetCurrentIndex("word");
if(pWords->Seek("=",&kw)) {
kwi=pWords->GetFieldValue("wid");
return kwi.lVal;
}
else
return -1;
}
long CMyDictionary::GetFreq(CString w)
{
COleVariant kw(w,VT_BSTRT),kf;
pWords->SetCurrentIndex("word");
if(pWords->Seek("=",&kw)) {
kf=pWords->GetFieldValue("wfreq");
return kf.lVal;
}
else return -1;
}
long CMyDictionary::GetFreq(CString w, CString t)
{// 查找某词以某标记出现的次数
long i=GetWordID(w); // 从词语words表中取词语标识号
if(i==-1) // 没有这个词
return 0;
COleVariant kwi(i,VT_I4),kt,kf;
pTags->SetCurrentIndex("wid");
if(!pTags->Seek("=",&kwi))
return 0;
while(!pTags->IsEOF())
{ // 如果在词性表poss中找到了词语标识号
kwi = pTags->GetFieldValue("wid"); // 取词性表poss中的当前记录的词语代号值
if(kwi.lVal != i) // 如果当前记录的wid值发生变化,表示已经不是正在查找的词,则终止查询
break;
kt=pTags->GetFieldValue("pos"); // 取当前记录的词性标记值
if(!strcmp((const char *)kt.pbVal,(const char*)t)) { // 找到词性标记吻合的记录
kf=pTags->GetFieldValue("pfreq"); // 取当前记录的频次值
return kf.lVal;
}
pTags->MoveNext(); // 移动记录指针到下一条记录
}
return -1; // 没有找到词性标记吻合的记录,返回-1
}
long CMyDictionary::GetFreq(CString w, CObArray & a)
{// 查找一个词语在词典中的所有词性标记的出现次数
long i;
for(i=0;i<a.GetSize();i++)
delete a[i];
a.RemoveAll();
i=GetWordID(w);
if(i==-1)
return 0;
pTags->SetCurrentIndex("wid");
CTagFreq * p;
COleVariant kwi(i,VT_I4), kt,kf;
if(!pTags->Seek("=",&kwi))
return 0;
while(!pTags->IsEOF()) {
kwi=pTags->GetFieldValue("wid");
if(kwi.lVal!=i)
break;
kt=pTags->GetFieldValue("pos");
kf=pTags->GetFieldValue("pfreq");
p=new CTagFreq((LPCSTR) (kt.bstrVal), kf.lVal);
a.Add(p);
pTags->MoveNext();
}
return a.GetSize();
}
long CMyDictionary::Insert(CString w, long freq)
{//向词库中的words表加入一个词在语料库中的出现次数信息,freq的缺省值为1
if(w.GetLength()>MaxWordLength || w=="") // w太长或为空
return -1;
COleVariant kw(w,VT_BSTRT), kf;
pWords->SetCurrentIndex("word");
if(pWords->Seek("=",&kw)) { // 如果这个词在词库中已经存在
kf=pWords->GetFieldValue("wfreq");
kf.lVal+=freq;
pWords->Edit();
pWords->SetFieldValue("wfreq",kf);
pWords->Update();
kf=pWords->GetFieldValue("wid");
}
else {// 如果这个词在词库中还不存在
long recn=pWords->GetRecordCount(); // 查现有记录个数
pWords->AddNew(); // 增加一条空白记录
pWords->SetFieldValue("word",kw); // 设置word字段的值为当前词语
kf=freq; // 对变量kf进行赋值
pWords->SetFieldValue("wfreq",kf); // 设置freq字段的值
kf.lVal=recn+1; // 在当前表中最后一条记录后添加一条新记录
pWords->SetFieldValue("wid",kf); // 设置 wid字段的值
pWords->Update(); // 更新数据库中的数据
}
return kf.lVal; // 返回该词语的 wid 信息(词语代号)
}
long CMyDictionary :: Insert(CString w, CString t, long freq)
{// 向词库中words表和poss表分别插入一个词以某种词性出现的次数,freq的缺省值为1
if(w.GetLength()>MaxWordLength || w=="" || t.GetLength()>4 || t=="")
return -1;
long i=Insert(w); // 先更新词表中的词频信息,将该词的出现次数加1
COleVariant kt(t,VT_BSTRT), kwi(i,VT_I4), kf;
pTags->SetCurrentIndex("widTag");
if(pTags->Seek("=",&kwi,&kt)) {
kf=pTags->GetFieldValue("pfreq"); // 获取当前记录的pfreq值
kf.lVal+=freq;
pTags->Edit();
pTags->SetFieldValue("pfreq",kf); // 设置poss表中pfreq中的值
pTags->Update();
kf=pTags->GetFieldValue("pid"); // 获取当前记录的pid值
}
else {
long recn=pTags->GetRecordCount();
pTags->AddNew();
pTags->SetFieldValue("pos",kt); // 设置poss表中pos字段的值
kf=freq;
pTags->SetFieldValue("pfreq",kf); // 设置poss表中pfreq字段的值
pTags->SetFieldValue("wid",kwi); // 设置poss表中wid字段的值
kf.lVal=recn+1; // 在当前表中最后一条记录后添加一条新记录
pTags->SetFieldValue("pid",kf); // 设置poss表中pid字段的值
pTags->Update();
}
return kf.lVal;// 返回词语的词性标记序号值pid(词性标记代号)
}
///////////////////////////////////////////////////////////
CString CMyDictionary::GetTagOfWord(CString w)
{ //获取一个词语的词性标记
CString tag="";
long i;
i=GetWordID(w);
if(i==-1)
tag="n"; // 所有未登录词的词性暂且假定为n
pTags->SetCurrentIndex("wid");
COleVariant kwi(i,VT_I4),kt;
if(!pTags->Seek("=",&kwi))
return tag;
// else { // 取该词在词库中第一个词性标记
// kt=pTags->GetFieldValue("pos");
// tag=kt.bstrVal;
// }
while(!pTags->IsEOF()) {// 取该词所有词性标记,切词后,将一个词所有的词性标记
// 加到分词符/后面
kwi=pTags->GetFieldValue("wid");
if(kwi.lVal!=i)
break; // 如果当前词只有一个词性,并且标记为g,也会输出这个结果
kt=pTags->GetFieldValue("pos");
tag=kt.bstrVal; // 这条语句是为了只输出一个词性标记结果而添加的
// if(tag!="") { // 被注释的语句是用来输出所有的词性标记
if(tag!="g") { // 这里是只输出一个词性标记,并且该标记不是语素
// tag=tag+"-"+kt.bstrVal;
return tag;
}
else
// tag=tag+kt.bstrVal;
pTags->MoveNext();
}
return tag;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -