📄 dlgcreate.cpp
字号:
while (*p && !(isascii(*p) && isalpha(*p)))
{
if (!isascii(*p))
p++;
p++;
}
if (*p=='\0')
return -1;
else
return (p-str)/3;
}
////////////////////////////////////////////////////////////////
//判定字符串中位置i处的英文字符之后紧接着的非英文字符是不是等号
////////////////////////////////////////////////////////////////
int CDlgCreate::eq_after_it(CString str,int i)
{
int k=i;
int len=str.GetLength();
if (k>=len)
return 0;
while(k<len && isascii(str.GetAt(k)) && isalpha(str.GetAt(k)))
k++;
if (k>=len)
return 0;
else if (str.GetAt(k)!='=')
return 0;
return 1;
}
////////////////////////////////////////////////
// 根据数组建立《知网》数据库的表entity的结构
// 结构体struct fieleds_len entity_fields_len的各个元素
// 的值对应表entity各个字段的长度
////////////////////////////////////////////////
void CDlgCreate::build_hownet_entitystru(CString filename_to_build,struct fieleds_len entity_fields_len)
{
CDaoDatabase myDatabase;
myDatabase.Open(filename_to_build);
// 建立表entity,存放的内容是《知网》词典
CDaoTableDef *pTable;
pTable=new CDaoTableDef(&myDatabase);
pTable->Create("entity");
pTable->CreateField("序号",dbLong,entity_fields_len.len_order);
pTable->CreateField("名称",dbText,entity_fields_len.len_name+5);
pTable->CreateField("属性",dbText,entity_fields_len.len_attr+5);
pTable->CreateField("层次",dbLong,entity_fields_len.len_layer);
pTable->CreateField("父亲",dbLong,entity_fields_len.len_parent);
pTable->CreateField("儿子",dbLong,entity_fields_len.len_son);
pTable->CreateField("兄弟",dbLong,entity_fields_len.len_brother);
pTable->Append(); // 将表dict结构存入词库
pTable->Close();
delete pTable;
myDatabase.Close();
}
//////////////////////////////////////////////////////
// 建立表event,存放《知网》的event层次体系
//////////////////////////////////////////////////////
int CDlgCreate::build_event(CString event_txt_file, CString hownet_database_file, int &i_max_event_name_len)
{
int i_read_pointer;
struct fieleds_len event_fields_len;
// 建立动词event层次树
i_read_pointer=-1;
i_read_pointer=build_layer_tree(event_txt_file,NODE,MAX_EVENT_NUMBER,event_fields_len);
if (i_read_pointer==-1)
return -1;
//输出建立的动词event层次树到数据库中
int i_to_database=put_layer_tree_to_database(hownet_database_file,NODE,i_read_pointer,event_fields_len);
if (i_read_pointer==-1)
return -1;
i_max_event_name_len=event_fields_len.len_name;
return 0;
}
////////////////////////////////////////////////
//
// 建立event义原层次结构树
//
////////////////////////////////////////////////
int CDlgCreate::build_layer_tree(CString FileName,event_tree *NODE,int max_read_number,struct fieleds_len &event_fields_len)
{
//定义后进先出栈
int STACK[MAX_ENTITY_LAYER]; //里面存放的是节点在NODE[]中的位置
//定义节点的指针(只是一些数,指示节点的位置)
int i_read_pointer;
//定义栈的指针
int i_stack_pointer;
// 初始化event_fields_len
event_fields_len.len_name=0;
event_fields_len.len_attr=0;
event_fields_len.len_order=4;
event_fields_len.len_layer=4;
event_fields_len.len_parent=4;
event_fields_len.len_son=4;
event_fields_len.len_brother=4;
//打开选定的文件
CStdioFile inFile;
if (!inFile.Open(FileName,CFile::modeRead))
{
CString TempStr;
TempStr.Format("%s%s","无法读取文件:",FileName);
AfxMessageBox(TempStr);
return -1;
}
//一行行地读取文件直到文件结束
i_read_pointer=0;
i_stack_pointer=-1;
char s[MAX_LINE_LEN]; //定义s存放读入的字符串,这里MAX_LINE_LEN是一个预先定
//义的常量,一行的最大允许字符的个数
while(inFile.ReadString(s,MAX_LINE_LEN))
{
if (strlen(s)==0)
continue;
//节点赋初值
CString event_name="",event_role="";
get_name_role(s,event_name,event_role);
del_englidh_info(event_name);
if (event_name.GetLength()>event_fields_len.len_name)
event_fields_len.len_name=event_name.GetLength();
if (event_role.GetLength()>event_fields_len.len_attr)
event_fields_len.len_attr=event_role.GetLength();
NODE[i_read_pointer].event_name=event_name;
NODE[i_read_pointer].event_role=event_role;
if (NODE[i_read_pointer].event_name=="")
NODE[i_read_pointer].event_name="*";
if (NODE[i_read_pointer].event_role=="")
NODE[i_read_pointer].event_role="*";
NODE[i_read_pointer].order=i_read_pointer;
NODE[i_read_pointer].son=-1;
NODE[i_read_pointer].brother=-1;
NODE[i_read_pointer].parent=-1;
//确定节点的层次
NODE[i_read_pointer].layer=get_layer(s);
if (NODE[i_read_pointer].layer<0)
{
CString msg;
msg.Format("建立层次树的时候出了问题,请检查源文件\n%s 第 %d 行",FileName,i_read_pointer+1);
MessageBox(msg);
return -1;
}
//建立动词义原层次树
if (i_stack_pointer==-1) //如果栈为空,刚读到的节点是根节点
{
NODE[i_read_pointer].layer=0;
i_stack_pointer=0;
STACK[i_stack_pointer]=NODE[i_read_pointer].order;
}
else //刚读到的节点不是根节点,要入栈
{
//如果是栈顶节点的层次大于当前节点的层次
//那么应该退栈,直到前者小与或者等于后者
while (NODE[STACK[i_stack_pointer]].layer>NODE[i_read_pointer].layer)
{
i_stack_pointer--;
if (i_stack_pointer<0)
{
CString msg;
msg.Format("建立层次树的时候出了问题,请检查源文件\n%s 第 %d 行",FileName,i_read_pointer+1);
MessageBox(msg);
return -1;
}
}
if (NODE[STACK[i_stack_pointer]].layer==NODE[i_read_pointer].layer)
//栈顶节点与当前节点是兄弟关系
{
NODE[STACK[i_stack_pointer]].brother=NODE[i_read_pointer].order;
NODE[i_read_pointer].parent=NODE[STACK[i_stack_pointer]].parent;
STACK[i_stack_pointer]=NODE[i_read_pointer].order;
}
else if (NODE[STACK[i_stack_pointer]].layer==NODE[i_read_pointer].layer-1)
//栈顶节点与当前节点是父子关系
{
NODE[i_read_pointer].parent=STACK[i_stack_pointer];
NODE[STACK[i_stack_pointer]].son=NODE[i_read_pointer].order;
i_stack_pointer++;
STACK[i_stack_pointer]=NODE[i_read_pointer].order;
}
else
{
CString msg;
msg.Format("建立层次树的时候出了问题,请检查源文件\n%s 第 %d 行",FileName,i_read_pointer+1);
MessageBox(msg);
return -1;
}
}
i_read_pointer++;
if (i_read_pointer>=max_read_number)
{
CString msg;
msg.Format("建立层次树的时候出了问题,源文件\n%s 行数太多,预留数组空间不足",FileName);
MessageBox(msg);
return -1;
}
}
inFile.Close();
return i_read_pointer;
}
////////////////////////////////////////////
//
// 获得event义原的名字和角色
//
////////////////////////////////////////////
void CDlgCreate::get_name_role(char *str,CString &event_name,CString &event_role)
{
event_name=event_role="";
char *p,*q;
char fetch_str[MAX_LINE_LEN];
p=str;
//定位到第一个英文字母
while (*p && !(isascii(*p) && isalpha(*p)))
{
if (!isascii(*p))
p++;
p++;
}
if (*p=='\0')
return;
//开始拷贝动词义原的名字
q=fetch_str;
while (*p && !(isascii(*p) && (isspace(*p) || *p=='{')))
{
if (!isascii(*p))
*q++=*p++;
*q++=*p++;
}
*q='\0';
event_name=fetch_str;
//定位到第一个"{"
while (*p && *p!='{')
{
if (!isascii(*p))
p++;
p++;
}
if (*p=='\0')
return;
p++;
//开始拷贝动词角色的名字
q=fetch_str;
while (*p && *p!='}')
{
if (!isascii(*p))
*q++=*p++;
*q++=*p++;
}
*q='\0';
event_role=fetch_str;
}
///////////////////////////////////////////////
//
// 把event事件层次树填入数据库的event表
//
///////////////////////////////////////////////
int CDlgCreate::put_layer_tree_to_database(CString FileName_out, struct event_tree *NODE,int i_write_pointer,struct fieleds_len event_fields_len)
{
// 建立表event
build_hownet_eventstru(FileName_out,event_fields_len);
// 打开数据库FileName_out
CDaoDatabase myDatabase;
myDatabase.Open(FileName_out);
// 打开存放event层次关系的表event
CDaoTableDef *pTable;
pTable=new CDaoTableDef(&myDatabase);
pTable->Open("event");
// 对应表dict打开记录集
CDaoRecordset *pRec;
pRec=new CDaoRecordset(&myDatabase);
pRec->Open(pTable);
//输出建立的event层次树导数据库的表event
struct record
{
CString COrder;
CString CName;
CString CAttr;
CString CLayer;
CString CParent;
CString CSon;
CString CBrother;
}REC;
COleVariant cole_order;
COleVariant cole_name(REC.CName,VT_BSTRT);
COleVariant cole_attr(REC.CAttr,VT_BSTRT);
COleVariant cole_layer;
COleVariant cole_parent;
COleVariant cole_son;
COleVariant cole_brother;
for (int i=0;i<i_write_pointer;i++)
{
pRec->AddNew();
cole_order=(long)NODE[i].order;
pRec->SetFieldValue("序号",cole_order);
REC.CName.Format("%s",NODE[i].event_name);
cole_name.SetString(REC.CName,VT_BSTRT);
pRec->SetFieldValue("名称",cole_name);
REC.CAttr.Format("%s",NODE[i].event_role);
cole_attr.SetString(REC.CAttr,VT_BSTRT);
pRec->SetFieldValue("属性",cole_attr);
cole_layer=(long)NODE[i].layer;
pRec->SetFieldValue("层次",cole_layer);
cole_parent=(long)NODE[i].parent;
pRec->SetFieldValue("父亲",cole_parent);
cole_son=(long)NODE[i].son;
pRec->SetFieldValue("儿子",cole_son);
cole_brother=(long)NODE[i].brother;
pRec->SetFieldValue("兄弟",cole_brother);
pRec->Update();
}
pRec->Close();
delete pRec;
pTable->Close();
delete pTable;
myDatabase.Close();
/*
//输出建立的层次树之二-----调试程序
CString FileName_out2=FileName_out+".txt";
CStdioFile outFile;
if (!outFile.Open(FileName_out2,CFile::modeCreate|CFile::modeWrite))
{
CString TempStr;
TempStr.Format("%s%s","无法创建文件:",FileName_out2);
AfxMessageBox(TempStr);
return -1;
}
for (int k=0;k<i_write_pointer;k++)
{
CString s_wr="";
for(int j=0;j<NODE[k].layer*3+2;j++)
s_wr+=" ";
s_wr+=NODE[k].entity_name;
s_wr+=" ";
s_wr+=NODE[k].entity_attr;
s_wr+="\n";
outFile.WriteString(s_wr);
}
outFile.Close();
*/
return 0;
}
////////////////////////////////////////////////
// 根据数组建立《知网》数据库的表event的结构
// 结构体struct fieleds_len event_fields_len的各个元素
// 的值对应表event各个字段的长度
////////////////////////////////////////////////
void CDlgCreate::build_hownet_eventstru(CString filename_to_build,struct fieleds_len event_fields_len)
{
CDaoDatabase myDatabase;
myDatabase.Open(filename_to_build);
// 建立表entity,存放的内容是《知网》词典
CDaoTableDef *pTable;
pTable=new CDaoTableDef(&myDatabase);
pTable->Create("event");
pTable->CreateField("序号",dbLong,event_fields_len.len_order);
pTable->CreateField("名称",dbText,event_fields_len.len_name+5);
pTable->CreateField("属性",dbText,event_fields_len.len_attr+5);
pTable->CreateField("层次",dbLong,event_fields_len.len_layer);
pTable->CreateField("父亲",dbLong,event_fields_len.len_parent);
pTable->CreateField("儿子",dbLong,event_fields_len.len_son);
pTable->CreateField("兄弟",dbLong,event_fields_len.len_brother);
pTable->Append(); // 将表dict结构存入词库
pTable->Close();
delete pTable;
myDatabase.Close();
}
////////////////////////////////////////////////
// 字符指针p指向某个词的DEF
// 现在求其第一义原
// 一般来说,第一义原就是其第一个逗号之前的部分
// 如果该部分是“属性”、“属性值”或者“部件”
// 那么,第一义原取第一个逗号之后第二个逗号之前的部分
// 本函数调用求第一义原的函数
////////////////////////////////////////////////
CString CDlgCreate::get_first_sem(char *p)
{
CString str;
CString first;
str=p;
del_englidh_info(str);
// 寻找第一个逗号之前的部分,存入变量first
int k;
for (k=0;k<str.GetLength();k++)
{
if (str.GetAt(k)==',')
break;
if (!isascii(str.GetAt(k)))
k++;
}
first=str.Left(k);
if (first=="属性" || first=="属性值" || first=="部件")
{ // first=上述三者之一,需要再找第二部分
if (k>=str.GetLength()) // 没有第二部分,返回空字符串
first="";
else
{
// 下面把找到第二部分起点
str=str.Right(str.GetLength()-k);
for(k=0;k<str.GetLength();k++)
{
if (!isascii(str.GetAt(k)))
break;
}
str=str.Right(str.GetLength()-k);
if (str.GetLength()==0)
first="";
else
{
// 下面开始找第一义原
for (k=0;k<str.GetLength();k++)
{
if (str.GetAt(k)==',')
break;
if (!isascii(str.GetAt(k)))
k++;
}
first=str.Left(k);
}
}
}
return first;
}
////////////////////////////////////////////////
// 建立《知网》数据库的临时表temp的结构
// 参数i_name_len对应临时表当中的“名称”字段的长度
////////////////////////////////////////////////
int CDlgCreate::build_temp(int i_name_len, CString filename_to_build)
{
CDaoDatabase myDatabase;
myDatabase.Open(filename_to_build);
// 建立表temp,以便存放表entity或者表event的序号和名称
CDaoTableDef *pTable;
pTable=new CDaoTableDef(&myDatabase);
pTable->Create("temp");
pTable->CreateField("序号",dbLong,4);
pTable->CreateField("名称",dbText,i_name_len+5);
pTable->Append(); // 将表dict结构存入词库
pTable->Close();
delete pTable;
myDatabase.Close();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -