CTSC23 公式编辑器.docx

上传人:b****6 文档编号:4386584 上传时间:2022-12-01 格式:DOCX 页数:15 大小:21.08KB
下载 相关 举报
CTSC23 公式编辑器.docx_第1页
第1页 / 共15页
CTSC23 公式编辑器.docx_第2页
第2页 / 共15页
CTSC23 公式编辑器.docx_第3页
第3页 / 共15页
CTSC23 公式编辑器.docx_第4页
第4页 / 共15页
CTSC23 公式编辑器.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

CTSC23 公式编辑器.docx

《CTSC23 公式编辑器.docx》由会员分享,可在线阅读,更多相关《CTSC23 公式编辑器.docx(15页珍藏版)》请在冰豆网上搜索。

CTSC23 公式编辑器.docx

CTSC23公式编辑器

公式编辑器解题报告

湖南省长沙市长郡中学胡伟栋

问题简述:

给出键盘的一些操作,要求编一个程序模拟公式编辑器处理这些操作。

公式编辑器支持以下操作:

输入字符、插入分式、插入矩阵、插入一行或一列到矩阵中、光标上下左右移动、光标移到编辑框首、光标移到编辑框尾。

分析:

此题是一道很复杂的模拟题。

此题难点在于其对象的类型比较多:

有字符、矩阵和分式,同时操作比较多:

有光标的上下左右移动、Home、End,矩阵的增加行、列等。

且输出也比较麻烦。

解决此题主要是保持头脑清醒(这一点对做任何模拟题都非常重要)和选择好的数据结构。

这里,整个表达式很像一棵树的样子:

如果一个表达式不是整个表达式,则它必有一个直接的包含它的表达式,这就是它的父表达式;每个表达式都可能有0个或多个子表达式且子表达式之间没有直接关系。

可以用树结构来处理整个表达式。

此题是一个模拟题,不要用到多少算法,只要按照原题所说的一步一步做即可。

具体做法可见参考程序。

参考程序:

program

Maths;

{$ModeDelphi}//引用Delphi模式

const

inf='maths.in';//输入文件

ouf='maths.out';//输出文件

maxChars=100000;//输出的非空字符最大数

type

eleStyle=(eleChar,eleExp,eleMatrix,eleFraction);//表达式的类型

placeType=(pl_None,pl_Home,pl_End);//不移动/移到编缉框开始位置/移到编缉框结束位置

const

hs:

array[eleChar..eleFraction]ofinteger=(0,1,1,2);//不同表达式的初始行数

ws:

array[eleChar..eleFraction]ofinteger=(0,0,1,1);//不同表达式的初始列数

moveSetPlace:

array[-1..1]ofplaceType=(pl_End,pl_None,pl_Home);//向左(-1)/右

(1)移动到子编辑框的位置

ifEnd:

array[-1..1]ofinteger=(1,0,0);//向左(-1)/右

(1)移动是否会到子编辑框的结束位置

canMin:

array[eleChar..eleFraction]ofinteger=(0,0,1,1);//编辑框的光标能向左移的最小位置

type

canvasType=object//所有非空字符输出队列

l:

integer;//字符数

pos:

array[-1..maxChars,1..2]ofinteger;//输出位置

chars:

array[0..maxChars]ofchar;//输出字符,#0表示分数线

procedurePrintChar(y,x:

integer;ch:

char);//在第y行第x列输出一个字符ch

proceduresort(_From,_To:

integer);//将字符按行列位置排序

procedureSave(fileName:

string);//输出到文件

end;

eleType=class//表达式的基类

fParent:

eleType;//父达式

fStyle:

eleStyle;//表达式类型

h,w:

integer;//h为行数,w为列数

pos:

array[1..2]ofinteger;//若当前编辑焦点在这个表达式的子表达式中,则指向对应子表达式的位置

Width,Height,UpHeight,DownHeight:

integer;//输出宽度,高度,对齐行上方的高度,对齐行下方的高度

constructorcreate(parent:

eleType;style:

eleStyle);//构造类并初始化

functiongetS(y,x:

integer):

eleType;//取得y行x列的子表达式

proceduresetS(y,x:

integer;Value:

eleType);//设置y行x列的子表达式

proceduresetFocus(place:

placeType);//设置编辑焦点

proceduremoveHome;//光标移动到行首(虽然只可能在expType子类中调用此过程,但为了便于调用,将它放在基类中)

proceduremoveEnd;//光标移动到行尾(虽然只可能在expType子类中调用此过程,但为了便于调用,将它放在基类中)

proceduremoveUpOrDown(incs:

integer);//光标上移(incs=-1)或下移(incs=1)一行

proceduremoveLeftOrRight(incs:

integer);//光标左移(incs=-1)或右移(incs=1)一行

procedureAddCol;//添加一列

procedureAddRow;//添加一行

procedureAddOne(ele:

eleType);//将一个表达式添加到光标位置(虽然只可能在expType子类中调用此过程,但为了便于调用,将它放在基类中)

proceduregetPrintMessage;//得到输出的信息(应输出行数、列数等)

procedurePrint(HCenter,Left:

integer);//将表达式输出到输出队列中

propertys[y,x:

integer]:

eleTypereadgetSwritesetS;//子表达式。

这是一个属性,取值时相当于调用getS(y,x);给它赋值时相当于调用setS(y,x,value),其中value为所赋的值

end;

charType=class(eleType)//字符子类

Dat:

char;//所存储的运算数或运算符

end;

expType=class(eleType)//编辑框子类

fs:

array[1..1,1..500]ofeleType;//编辑框内的子表达式

end;

matrixType=class(eleType)//矩阵子类

fs:

array[1..10,1..10]ofeleType;//矩阵中的子表达式

Heights,UpHeights,DownHeights,Widths:

array[1..10]ofinteger;//输出时每行对应的高度、对齐行上方的高度、对齐行下方的高度及每列对应的最大宽度

end;

fractionType=class(eleType)//分式子类

fs:

array[1..2,1..1]ofeleType;//分式中的子表达式

end;

var

root,//整个表达式

action:

eleType;//当前的焦点表达式

screen:

canvasType;//输出队列

functionmax(a,b:

integer):

integer;//求a,b的最大值

begin

ifa>bthenmax:

=aelsemax:

=b;

end;

procedurecanvasType.PrintChar(y,x:

integer;ch:

char);

begin

ifch='-'theninc(x)else

ifch=#0thench:

='-';

inc(l);

pos[l,1]:

=y;pos[l,2]:

=x;

chars[l]:

=ch;

end;

procedurecanvasType.sort(_From,_To:

integer);

var

i,j:

integer;

begin

i:

=_From;j:

=_To;pos[-1]:

=pos[(i+j)shr1];

whilei<=jdo

begin

while(pos[i,1]

while(pos[j,1]>pos[-1,1])or(pos[j,1]=pos[-1,1])and(pos[j,2]>pos[-1,2])dodec(j);

ifi<=jthen

begin

pos[0]:

=pos[i];pos[i]:

=pos[j];pos[j]:

=pos[0];

chars[0]:

=chars[i];chars[i]:

=chars[j];chars[j]:

=chars[0];

inc(i);dec(j);

end;

end;

ifj>_Fromthensort(_From,j);

ifi<_Tothensort(i,_To);

end;

procedurecanvasType.Save(fileName:

string);

var

cur:

array[1..2]ofinteger;

i,j:

integer;

begin

sort(1,l);

assign(output,fileName);rewrite(output);

cur[1]:

=1;cur[2]:

=1;

fori:

=1toldo

begin

ifcur[1]<>pos[i,1]thencur[2]:

=1;

forj:

=cur[1]+1topos[i,1]do

writeln;

write(chars[i]:

pos[i,2]-cur[2]+1);

cur[1]:

=pos[i,1];

cur[2]:

=pos[i,2]+1;

end;

writeln;

close(output);

end;

constructoreleType.create(parent:

eleType;style:

eleStyle);

var

i:

integer;

begin

fParent:

=parent;

fStyle:

=style;

h:

=hs[style];

w:

=ws[style];

pos[1]:

=1;

pos[2]:

=1;

if(fStyle=eleMatrix)or(fStyle=eleFraction)then//如果是矩阵或分式,则一开始就应该有1或2个子编辑框

fori:

=1tohdo

s[i,1]:

=expType.create(self,eleExp);

end;

functioneleType.getS(y,x:

integer):

eleType;

begin

casefStyleof//对不同的子类得到第y行第x列的子表达式

eleExp:

getS:

=expType(self).fs[y,x];

eleMatrix:

getS:

=matrixType(self).fs[y,x];

eleFraction:

getS:

=fractionType(self).fs[y,x];

elsegetS:

=nil;

end;

end;

procedureeleType.setS(y,x:

integer;value:

eleType);

begin

casefStyleof//对不同的子类设置第y行第x列的子表达式

eleExp:

expType(self).fs[y,x]:

=value;

eleMatrix:

matrixType(self).fs[y,x]:

=value;

eleFraction:

fractionType(self).fs[y,x]:

=value;

end;

end;

procedureeleType.setFocus(place:

placeType);

begin

action:

=self;

caseplaceof//设置焦点时可顺便确定光标位置

pl_Home:

moveHome;

pl_End:

moveEnd;

end;

end;

procedureeleType.moveHome;

begin

pos[2]:

=0;

end;

procedureeleType.moveEnd;

begin

pos[2]:

=w;

end;

procedureeleType.moveUpOrDown(incs:

integer);

begin

if(pos[1]+incs>=1)and(pos[1]+incs<=h)then//当前表达式可以上/下移动则移动

begin

inc(pos[1],incs);

s[pos[1],pos[2]].setFocus(pl_Home);

end

else//当前表达式不可上/下移动则由上一级表达式移动

iffParent<>nilthen

fParent.moveUpOrDown(incs);

end;

procedureeleType.moveLeftOrRight(incs:

integer);

procedureparentMove;//使用上一级表达式移动

begin

iffParent<>nilthen

begin

iffParent.fStyle=eleExpthen

begin

ifincs=-1thendec(fParent.pos[2]);

incs:

=0;

end;

fParent.moveLeftOrRight(incs);

end;

end;

var

p:

integer;

begin

ifincs=0thensetFocus(pl_None)else

if(pos[2]+incsw)thenparentMoveelse//如果当前表达式不能移动,则使用上一级表达式移动

casefStyleof

eleExp:

begin

p:

=max(pos[2],pos[2]+incs);

cases[pos[1],p].fStyleof//如果子表达式是矩阵或分式,则将光标移到子表达式中,否则直接改变光标位置

eleMatrix,eleFraction:

begin

pos[2]:

=p;

withs[pos[1],p]do

begin

pos[1]:

=(h+1)shr1;

pos[2]:

=(1+ifEnd[incs]*(w-1));

s[pos[1],pos[2]].setFocus(moveSetPlace[incs]);

end;

end;

elseinc(pos[2],incs);

end;

end;

eleMatrix:

begin

inc(pos[2],incs);

s[pos[1],pos[2]].setFocus(moveSetPlace[incs]);

end;

elseparentMove;//分式要使用上一级表达式移动

end;

end;

procedureeleType.AddRow;

var

i,j:

integer;

begin

iffStyle=eleMatrixthen//如果当前是一个矩阵,则添加一行,否则看上一级表达式能否添加行

begin

fori:

=hdowntopos[1]do

forj:

=1towdo

s[i+1,j]:

=s[i,j];

inc(h);

forj:

=1towdo

s[pos[1],j]:

=expType.create(self,eleExp);

s[pos[1],pos[2]].setFocus(pl_Home);

end

else

iffParent<>nilthenfParent.AddRow;

end;

procedureeleType.AddCol;

var

i,j:

integer;

begin

iffStyle=eleMatrixthen//如果当前是一个矩阵,则添加一列,否则看上一级表达式能否添加列

begin

forj:

=wdowntopos[2]do

fori:

=1tohdo

s[i,j+1]:

=s[i,j];

inc(w);

fori:

=1tohdo

s[i,pos[2]]:

=expType.create(self,eleExp);

s[pos[1],pos[2]].setFocus(pl_Home);

end

else

iffParent<>nilthenfParent.AddCol;

end;

procedureeleType.AddOne(ele:

eleType);

var

i:

integer;

begin

fori:

=wdowntopos[2]+1do

s[1,i+1]:

=s[1,i];

inc(w);

s[1,pos[2]+1]:

=ele;

moveLeftOrRight

(1);

end;

procedureeleType.getPrintMessage;

var

i,j:

integer;

begin

Width:

=0;UpHeight:

=0;DownHeight:

=0;

casefStyleof

eleChar:

begin

UpHeight:

=0;DownHeight:

=0;

ifcharType(self).Dat='-'thenWidth:

=3elseWidth:

=1;

end;

eleExp:

fori:

=1towdo

begin

s[1,i].getPrintMessage;

inc(Width,s[1,i].Width);

UpHeight:

=max(UpHeight,s[1,i].UpHeight);

DownHeight:

=max(DownHeight,s[1,i].DownHeight);

end;

eleMatrix:

withmatrixType(self)do

begin

fillchar(UpHeights,sizeof(UpHeights),0);

fillchar(DownHeights,sizeof(DownHeights),0);

fillchar(Widths,sizeof(Widths),0);

fori:

=1tohdo

begin

forj:

=1towdo

begin

s[i,j].getPrintMessage;

UpHeights[i]:

=max(UpHeights[i],s[i,j].UpHeight);

DownHeights[i]:

=max(DownHeights[i],s[i,j].DownHeight);

Widths[j]:

=max(Widths[j],s[i,j].Width);

end;

Heights[i]:

=UpHeights[i]+DownHeights[i]+1;

end;

fori:

=1towdo

inc(Width,Widths[i]+1);

inc(Width);

fori:

=1tohshr1do

inc(UpHeight,Heights[i]+1);

dec(UpHeight);

ifodd(h)then

inc(UpHeight,1+UpHeights[hshr1+1]);

fori:

=hdowntoh-hshr1+1do

inc(DownHeight,Heights[i]+1);

dec(DownHeight);

ifodd(h)then

inc(DownHeight,1+DownHeights[hshr1+1]);

end;

eleFraction:

begin

s[1,1].getPrintMessage;

s[2,1].getPrintMessage;

UpHeight:

=s[1,1].Height;

DownHeight:

=s[2,1].Height;

Width:

=max(s[1,1].Width,s[2,1].Width)+2;

end;

end;

Height:

=UpHeight+DownHeight+1;

end;

procedureeleType.Print(HCenter,Left:

integer);

var

Top,L,i,j:

integer;

begin

casefStyleof

eleChar:

Screen.PrintChar(HCenter,Left,charType(self).Dat);

eleExp:

fori:

=1towdo

begin

s[1,i].Print(HCenter,Left);

inc(Left,s[1,i].Width);

end;

eleMatrix:

withmatrixType(self)do

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 预防医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1