ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:21.08KB ,
资源ID:4386584      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4386584.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(CTSC23 公式编辑器.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

CTSC23 公式编辑器.docx

1、CTSC23 公式编辑器公式编辑器 解题报告湖南省长沙市长郡中学 胡伟栋问题简述:给出键盘的一些操作,要求编一个程序模拟公式编辑器处理这些操作。公式编辑器支持以下操作:输入字符、插入分式、插入矩阵、插入一行或一列到矩阵中、光标上下左右移动、光标移到编辑框首、光标移到编辑框尾。分析:此题是一道很复杂的模拟题。此题难点在于其对象的类型比较多:有字符、矩阵和分式,同时操作比较多:有光标的上下左右移动、Home、End,矩阵的增加行、列等。且输出也比较麻烦。解决此题主要是保持头脑清醒(这一点对做任何模拟题都非常重要)和选择好的数据结构。这里,整个表达式很像一棵树的样子:如果一个表达式不是整个表达式,则

2、它必有一个直接的包含它的表达式,这就是它的父表达式;每个表达式都可能有0个或多个子表达式且子表达式之间没有直接关系。可以用树结构来处理整个表达式。此题是一个模拟题,不要用到多少算法,只要按照原题所说的一步一步做即可。具体做法可见参考程序。参考程序:program Maths;$Mode Delphi / 引用Delphi模式const inf = maths.in; / 输入文件 ouf = maths.out; / 输出文件 maxChars = 100000; / 输出的非空字符最大数type eleStyle = (eleChar, eleExp, eleMatrix, eleFract

3、ion); / 表达式的类型 placeType = (pl_None, pl_Home, pl_End); / 不移动/移到编缉框开始位置/移到编缉框结束位置const hs : arrayeleChar.eleFraction of integer = (0, 1, 1, 2); / 不同表达式的初始行数 ws : arrayeleChar.eleFraction of integer = (0, 0, 1, 1); / 不同表达式的初始列数 moveSetPlace : array-1.1 of placeType = (pl_End, pl_None, pl_Home); / 向左(-

4、1)/右(1)移动到子编辑框的位置 ifEnd : array-1.1 of integer = (1, 0, 0); / 向左(-1)/右(1)移动是否会到子编辑框的结束位置 canMin : arrayeleChar.eleFraction of integer = (0, 0, 1, 1); / 编辑框的光标能向左移的最小位置type canvasType = object / 所有非空字符输出队列 l : integer; / 字符数 pos : array-1.maxChars, 1.2 of integer; / 输出位置 chars : array0.maxChars of ch

5、ar; / 输出字符,#0表示分数线 procedure PrintChar(y, x : integer; ch : char); / 在第y行第x列输出一个字符ch procedure sort(_From, _To : integer); / 将字符按行列位置排序 procedure Save(fileName : string); / 输出到文件 end; eleType = class / 表达式的基类 fParent : eleType; / 父达式 fStyle : eleStyle; / 表达式类型 h, w : integer; / h为行数,w为列数 pos : array

6、1.2 of integer; / 若当前编辑焦点在这个表达式的子表达式中,则指向对应子表达式的位置 Width, Height, UpHeight, DownHeight : integer; / 输出宽度,高度,对齐行上方的高度,对齐行下方的高度 constructor create(parent : eleType; style : eleStyle); / 构造类并初始化 function getS(y, x : integer) : eleType; / 取得y行x列的子表达式 procedure setS(y, x : integer; Value : eleType); / 设置

7、y行x列的子表达式 procedure setFocus(place : placeType); / 设置编辑焦点 procedure moveHome; / 光标移动到行首(虽然只可能在expType子类中调用此过程,但为了便于调用,将它放在基类中) procedure moveEnd; / 光标移动到行尾(虽然只可能在expType子类中调用此过程,但为了便于调用,将它放在基类中) procedure moveUpOrDown(incs : integer); / 光标上移(incs=-1)或下移(incs=1)一行 procedure moveLeftOrRight(incs : int

8、eger); / 光标左移(incs=-1)或右移(incs=1)一行 procedure AddCol; / 添加一列 procedure AddRow; / 添加一行 procedure AddOne(ele : eleType); / 将一个表达式添加到光标位置(虽然只可能在expType子类中调用此过程,但为了便于调用,将它放在基类中) procedure getPrintMessage; / 得到输出的信息(应输出行数、列数等) procedure Print(HCenter, Left : integer); / 将表达式输出到输出队列中 property sy, x : inte

9、ger : eleType read getS write setS; / 子表达式。这是一个属性,取值时相当于调用getS(y,x);给它赋值时相当于调用setS(y,x,value),其中value为所赋的值 end; charType = class(eleType) / 字符 子类 Dat : char; / 所存储的运算数或运算符 end; expType = class(eleType) / 编辑框 子类 fs : array1.1, 1.500 of eleType; / 编辑框内的子表达式 end; matrixType = class(eleType) / 矩阵 子类 fs

10、: array1.10, 1.10 of eleType; / 矩阵中的子表达式 Heights, UpHeights, DownHeights, Widths : array1.10 of integer; / 输出时每行对应的高度、对齐行上方的高度、对齐行下方的高度及每列对应的最大宽度 end; fractionType = class(eleType) / 分式 子类 fs : array1.2, 1.1 of eleType; / 分式中的子表达式 end;var root, / 整个表达式 action : eleType; / 当前的焦点表达式 screen : canvasTyp

11、e; / 输出队列 function max(a, b : integer) : integer; / 求a,b的最大值 begin if a b then max := a else max := b; end; procedure canvasType.PrintChar(y, x : integer; ch : char); begin if ch = - then inc(x) else if ch = #0 then ch := -; inc(l); posl, 1 := y; posl, 2 := x; charsl := ch; end; procedure canvasType

12、.sort(_From, _To : integer); var i, j : integer; begin i := _From; j := _To; pos-1 := pos(i + j) shr 1; while i = j do begin while (posi, 1 pos-1, 1) or (posi, 1 = pos-1, 1) and (posi, 2 pos-1, 1) or (posj, 1 = pos-1, 1) and (posj, 2 pos-1, 2) do dec(j); if i _From then sort(_From, j); if i _To then

13、 sort(i, _To); end; procedure canvasType.Save(fileName : string); var cur : array1.2 of integer; i, j : integer; begin sort(1, l); assign(output, fileName); rewrite(output); cur1 := 1; cur2 := 1; for i := 1 to l do begin if cur1 posi, 1 then cur2 := 1; for j := cur1 + 1 to posi, 1 do writeln; write(

14、charsi : posi, 2 - cur2 + 1); cur1 := posi, 1; cur2 := posi, 2 + 1; end; writeln; close(output); end; constructor eleType.create(parent : eleType; style : eleStyle); var i : integer; begin fParent := parent; fStyle := style; h := hsstyle; w := wsstyle; pos1 := 1; pos2 := 1; if (fStyle = eleMatrix) o

15、r (fStyle = eleFraction) then / 如果是矩阵或分式,则一开始就应该有1或2个子编辑框 for i := 1 to h do si, 1 := expType.create(self, eleExp); end; function eleType.getS(y, x : integer) : eleType; begin case fStyle of / 对不同的子类得到第y行第x列的子表达式 eleExp : getS := expType(self).fsy, x; eleMatrix : getS := matrixType(self).fsy, x; ele

16、Fraction : getS := fractionType(self).fsy, x; else getS := nil; end; end; procedure eleType.setS(y, x : integer; value : eleType); begin case fStyle of / 对不同的子类设置第y行第x列的子表达式 eleExp : expType(self).fsy, x := value; eleMatrix : matrixType(self).fsy, x := value; eleFraction : fractionType(self).fsy, x

17、:= value; end; end; procedure eleType.setFocus(place : placeType); begin action := self; case place of / 设置焦点时可顺便确定光标位置 pl_Home : moveHome; pl_End : moveEnd; end; end; procedure eleType.moveHome; begin pos2 := 0; end; procedure eleType.moveEnd; begin pos2 := w; end; procedure eleType.moveUpOrDown(in

18、cs : integer); begin if (pos1 + incs = 1) and (pos1 + incs = h) then / 当前表达式可以上/下移动则移动 begin inc(pos1, incs); spos1, pos2.setFocus(pl_Home); end else / 当前表达式不可上/下移动则由上一级表达式移动 if fParent nil then fParent.moveUpOrDown(incs); end; procedure eleType.moveLeftOrRight(incs : integer); procedure parentMove;

19、 / 使用上一级表达式移动 begin if fParent nil then begin if fParent.fStyle = eleExp then begin if incs = -1 then dec(fParent.pos2); incs := 0; end; fParent.moveLeftOrRight(incs); end; end; var p : integer; begin if incs = 0 then setFocus(pl_None) else if (pos2 + incs w) then parentMove else / 如果当前表达式不能移动,则使用上一

20、级表达式移动 case fStyle of eleExp : begin p := max(pos2, pos2 + incs); case spos1, p.fStyle of / 如果子表达式是矩阵或分式,则将光标移到子表达式中,否则直接改变光标位置 eleMatrix, eleFraction : begin pos2 := p; with spos1, p do begin pos1 := (h + 1) shr 1; pos2 := (1 + ifEndincs * (w - 1); spos1, pos2.setFocus(moveSetPlaceincs); end; end;

21、else inc(pos2, incs); end; end; eleMatrix : begin inc(pos2, incs); spos1, pos2.setFocus(moveSetPlaceincs); end; else parentMove; / 分式要使用上一级表达式移动 end; end; procedure eleType.AddRow; var i, j : integer; begin if fStyle = eleMatrix then / 如果当前是一个矩阵,则添加一行,否则看上一级表达式能否添加行 begin for i := h downto pos1 do f

22、or j := 1 to w do si + 1, j := si, j; inc(h); for j := 1 to w do spos1, j := expType.create(self, eleExp); spos1, pos2.setFocus(pl_Home); end else if fParent nil then fParent.AddRow; end; procedure eleType.AddCol; var i, j : integer; begin if fStyle = eleMatrix then / 如果当前是一个矩阵,则添加一列,否则看上一级表达式能否添加列

23、begin for j := w downto pos2 do for i := 1 to h do si, j + 1 := si, j; inc(w); for i := 1 to h do si, pos2 := expType.create(self, eleExp); spos1, pos2.setFocus(pl_Home); end else if fParent nil then fParent.AddCol; end; procedure eleType.AddOne(ele : eleType); var i : integer; begin for i := w down

24、to pos2 + 1 do s1, i + 1 := s1, i; inc(w); s1, pos2 + 1 := ele; moveLeftOrRight(1); end; procedure eleType.getPrintMessage; var i, j : integer; begin Width := 0; UpHeight := 0; DownHeight := 0; case fStyle of eleChar : begin UpHeight := 0; DownHeight := 0; if charType(self).Dat = - then Width := 3 e

25、lse Width := 1; end; eleExp : for i := 1 to w do begin s1, i.getPrintMessage; inc(Width, s1, i.Width); UpHeight := max(UpHeight, s1, i.UpHeight); DownHeight := max(DownHeight, s1, i.DownHeight); end; eleMatrix : with matrixType(self) do begin fillchar(UpHeights, sizeof(UpHeights), 0); fillchar(DownH

26、eights, sizeof(DownHeights), 0); fillchar(Widths, sizeof(Widths), 0); for i := 1 to h do begin for j := 1 to w do begin si, j.getPrintMessage; UpHeightsi := max(UpHeightsi, si, j.UpHeight); DownHeightsi := max(DownHeightsi, si, j.DownHeight); Widthsj := max(Widthsj, si, j.Width); end; Heightsi := Up

27、Heightsi + DownHeightsi + 1; end; for i := 1 to w do inc(Width, Widthsi + 1); inc(Width); for i := 1 to h shr 1 do inc(UpHeight, Heightsi + 1); dec(UpHeight); if odd(h) then inc(UpHeight, 1 + UpHeightsh shr 1 + 1); for i := h downto h - h shr 1 + 1 do inc(DownHeight, Heightsi + 1); dec(DownHeight);

28、if odd(h) then inc(DownHeight, 1 + DownHeightsh shr 1 + 1); end; eleFraction : begin s1, 1.getPrintMessage; s2, 1.getPrintMessage; UpHeight := s1, 1.Height; DownHeight := s2, 1.Height; Width := max(s1, 1.Width, s2, 1.Width) + 2; end; end; Height := UpHeight + DownHeight + 1; end; procedure eleType.Print(HCenter, Left : integer); var Top, L, i, j : integer; begin case fStyle of eleChar : Screen.PrintChar(HCenter, Left, charType(self).Dat); eleExp : for i := 1 to w do begin s1, i.Print(HCenter, Left); inc(Left, s1, i.Width); end; eleMatrix : with matrixType(self) do

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

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