<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
组卷模块接受用户输入,然后通过数据库访问模块查找相应的模板,将各模板交给模板解释器,由模板解释器进行翻译。
动态几何模块,我们采用最小服务器模式开发,它完成动态几何的作图、显示、运动等。由模板解释器负责创建,并通过内存映射文件进行数据传递。
CStringstrObj=_T("gDrawServer.document");
//创建动态几何服务器
InsertObject(strObj,OLEIVERB_SHOW);
COleClientItem*pActiveItem=GetDocument()->GetInPlaceActiveItem(this);
if(pActiveItem!=NULL)
{
CWnd*pWnd=pActiveItem->GetInPlaceWindow();
//strCmd是一组动态几何数据
DWORDnSize=strCmd.GetLength()+2;
//创建内存映射文件
HANDLEhSharedMapFile=
CreateFileMapping((HANDLE)0xFFFFFFFF,
NULL,PAGE_READWRITE,0,nSize,"MySharedDraw");
if(hSharedMapFile)
{
//映射缓存区视图:
LPSTR pszSharedMapView = (LPSTR)MapViewOfFile(hSharedMapFile,
FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
if(pszSharedMapView)
{
strcpy(pszSharedMapView,strCmd);
UnmapViewOfFile(pszSharedMapView);
//发消息给服务器,
pWnd->SendMessage(
NOTIFY_DRAW_CURVE,0,0);
}
CloseHandle(hSharedMapFile);
}
pActiveItem->Close();
}
数学公式模块采用ActiveX组件开发,它完成数学公式编辑、显示等。由模板解释器负责创建,并通过数学公式模块提供的外部接口进行数据传递。
CStringstrObj=_T("FormulaEdit.FormulaEditCtrl.1");//创建公式
InsertObject(strObj,OLEIVERB_SHOW);
CMytrItem*pItem=(CMytrItem*)GetDocument()->
GetInPlaceActiveItem(this);
if(pItem)
{
pItem->EnableAutomation();
LPDISPATCHlpDisp;
lpDisp=pItem->GetIDispatch();
_DFormulaEditformula(lpDisp);
//strCmd:是需要显示的公式
formula.SetCaption(strCmd);
pItem->DeactivateUI();
}
3模板设计
在软件的开发中,我们采用题目模板和答案模板一一对应,将其和搜索关键字联系起来放入数据库。模板以格式化文本存放。
3.1模板格式
由于模板代表一类题目、或某些知识点,为此,我们定义了一组格式。
(1)%#a+b^2+c/2%#,表示a+b^2+c/2作为公式解释。
(2)%$string%$,string是一组动态几何数据。
(3)%%,作为%字符解释,即显示%。
(4)%1s第一个字符参数,类似%2s,%3s,…。
(5)、%ustring%u,string为字符串,表示string加下划线。
(6)、%astring%a,string需要符号演算。
………………………………………………
例如,如果模板数据为“已知%#x^2-5*x+1=0%#,求%#x^4+1/x^4%#的值。”
则,显示结果为:
已知,求的值。
3.2模板解释器
模板解释器是本文的核心,它负责将模板翻译成我们需要的文档,该文档支持图文混排。为此,我们设计了一个类:
classCZuJuanInfo//组卷
{
public:
CZuJuanInfo();
~CZuJuanInfo();
enum{MAXCOUNT=100};
//一次组卷最大题目数100
voidCreate_Paper(CMyView*);//组卷
voidCreate(intKm,intnKey,intnTx);
…………………………………………………..
protected:
intm_nDegree;//难度系数
TCHARm_szName[c_nameLen];//试卷名称
intm_nGrade;//----年级
intm_Km;//学科
………………..
structTypeInfo
{
intm_nTx;//题型
intm_nCount;//题数
};
structInfo
{//某类知识点的题型、题数
intm_nKey;//---------选中的知识点
CArray<TypeInfo,TypeInfo&>m_keyTm;
//关于m_nKey的题目
voidUpdate(intnTx,intnCount);
Info&operator=(Info&);
intGetTiMuCount();
};
CArray<Info,Info&>m_arrayTm;
};
在解释器中,一个重要的问题是生成实参以替换形参。因此,解释器的工作过程:
(1)从左到右扫描题目模板文本,将所有的形参找到,放到链表1中,我们用一个结构标记了形参在模板文本中的起始位置、参数类型、大小范围、原始串等等。
(2)在链表中根据参数类型生成实参。
(3)对题目模板文本从右到左进行参数替换,即用链表1中的实参替换模板文本中的形参。
(4)从左到右扫描答案模板文本,将所有的形参找到,放到链表2中。由于答案的形参一定在链表1中能找到,因此,这里我们用一个结构只标记了形参在答案模板文本中的起始位置,和链表1中对应的实参。
(5)对答案模板文本从右到左进行参数替换,即用链表2中的实参替换模板文本中的形参。
(6)分别扫描题目模板和答案模板,进行符号演算。即对有关代数式进行运算、化简等。
(7)分别扫描题目模板和答案模板,生成rtf格式文本、创建动态几何图形、数学公式组件等等。
3.3异常处理
系统的稳定性是非常重要的,我们在设计程序时,充分考虑到了该问题。如对于参数替换,由于输入模板的错误,导致在答案模板中出现的形参在题目模板中没有对应,或参数替换后出现整数除以0等等。又如下面方程组:
由于参数的不同,其解有三种可能:唯一解、无解和无穷多个解。
对于类似这些问题,系统都有模块处理。
4结论
本文通过将题目按知识点、题型等分类,建立相应模板,既实现了快速组卷又避免了试卷重复;将符号演算系统嵌入到系统,使得系统具有了智能性,由模板解释器对模板的分析解释,然后生成所需要的题目,根据题目再自动求解;通过组件技术,将数学公式写成控件,模板解释器通过控件的外部接口传递参数,使得该系统非常平滑地支持了数学公式的显示、编辑。在进一步的智能平台开发中,我们可以将它与专家系统的知识、概念有机地连为一体,建立一个完整的具有图形语义知识的题库系统。
参考文献
1朱大勇,郭四稳.基于动态作图的图形符号编辑系统[J].计算机工程.2003第29卷第18期:Page23-24
2Cardelli,L.,andWegner,P.[1985].Onunderstandingtypes,dataabstraction,andpolymorphism.ACMComputingSurveys17:4,471-522
3Joong-RinShin,Wook-HwaLee,Dong-HaeIm.Awindows-basedinteractiveandgraphicpackagefortheeducationandtrainingofpowersystemanalysisandoperation.IEEETransactionsonPowerSystems.(PWRS).vol.14.1999.no.4.p.1193-1199
4WilliamFord,WilliamTopp.陈君译.数据结构C++语言描述---应用标准模板库(STL).清华大学出版社,2003,5
5姜文清.编译技术原理.国防工业出版社,1994,7
6AdamDrozdesk著,陈曙晖译.数据结构与算法--C++版(第二版).清华大学出版社,2003,4
7MikeyWilliams著,前导工作室译.Windows2000编程技术内幕.机械工业出版社,1999,12
8北京希望电子出版设总策划,周鸣杨编著.VisualC++界面编程技术.北京希望电子出版,2003,2