出),所以空⑤应填K+SN(J)+1+LNW.这个里面分为4个部分:K,SN(J),1,LNW.K:单词J写入到L的起始位置;SN(J):单词J的长度;1:正常空格长度(题目要求“单词之间必须有一个或一个以上的空格”);LNW:行尾多余空格平均分配到每个间隔的空格长度。
接下来我们来看空⑥,是在“打印L”处理后的,也就是当处理完一行并打印后,就要执行⑥,这样⑥应该是为新的一行处理做准备的,也就是说⑥应是对某个变量的赋值。我们现在可以逐一考查,循环里用到的哪些变量在新起一行时,要重新赋值。从“LN+SN(I+1)→LN1”可以看出,这个变量就是LN,因为LN存的是当前行的字符总数,当一行打印完后,LN的值应重新算,所以空⑥应填SN(I)→LN。 问题2:由于题目对末行输出的要求是:“最后一个行只须左对齐,且单词之间均只有一个空格”,所以我们不必考虑把尾部空格散布到单词间隔中,所以与LNB、LNW有关的语句得删除或修改。e中应该去掉LNW改为:K+SN(J)+1,f、g、h可以删除。
问题3:前面我们已经把所有空都填补完整,所以现在只需把改动的地方代入到程序里,手动模拟程序执行一段就能知道是否可行了。当执行到时LN+SN(I)+1→LN1,我们已经能够看出问题了,如果第一个单词加了一个空格位,那么此行一定会多出一个空格,所以这种改法是不行的。 参考答案 【问题1】
① LN+1+SN(1) →LN1 ② LN1→LN
③ ? ④ <
⑤ K+1+LNW+SN(j) ⑥ SN(1) →LN 【问题2】
删去f、g、h框,将e改成K+1+LNW+WN(J) →K。 【问题3】 不能。
例题3(2000年软件设计师试题)
阅读下列说明和数据流图,如图3-47所示,回答问题1至问题4,将解答写在答卷的对应栏内。
销销销销销销销销销销销销IN[]0销k,0销p,I销iIN[i]:销销销销销≠(IN[i]=?=销销) 销=K+1销kIN[i]销POLISH[k]P:0销销A =≠销销BS[p]:’(‘≠销≤销销B(p-1)销p销销A>i+1销iP:0?≠销销B=销销POLISH[]销销
图3-47 例题4流程图
【说明】
本流程图(如图3-47所示)是将中缀表示算术表达式转换成后缀表示,如中缀表达式 (A-(B*C+D)*E/(F+G))的后缀表示为ABC*D+E*-FG+/。
为了方便,假定变量名为单个英文字母,运算符只有“+”、“-”、“×”和“∕”(均为双目运算符,左结合),并假定所提供的算术表达式非空且语法是正确的。另外,中缀表示形式中无空格符,但整个算术表达式以空格符结束。流程图中使用的符号的意义如下:
? 数组IN[]存储中缀表达式。
? 数组POLISH[]存储其后缀表示。 ? 数组S[]是一个后进先出栈;
函数PRIOR(CHAR)返回符号CHAR的优先级,各符号的优先级见表3-6。
表3-6 各符号的优先级 CHAR PRIOR(CHAR) *、/ +、- ( ) 4 3 2 1 【问题1】
填充流程图中□的判断条件。 【问题2】
写出子程序A的功能,并顺序写出实现该功能的操作。 【问题3】
写出子程序B的功能,并顺序写出实现该功能的操作。 【问题4】
中缀表达式(A+B-C*D)*(E-F)/G经该流程图处理后的输出是什么?
分析:根据流程图中的符号得定义知道,数组IN[]与POLISH[]是对输入与输出的存储;而PRIOR是一个提取算术运算符号优先值的函数,语句没有多少可以发挥得地方;对数组S【】得定义是一个先进后出的栈。在数据结构中,对于栈的定义了3种厂用电操作如果采用数组来实现栈,需要定义一个栈顶指针p,其值为数组下标,其操作解释如下;
? 入栈:p+1→p;入栈元素→S[p];
? 出栈: S[p] →栈元素变量; p-1→p; ? 栈是否为空:p=?0。
如果考生了解堆栈的常用操作,就可以分析流程图,并给出正确的答案。 根据流程图可以得到如下得提示: ? 3个变量:k,p,I.
? 根据第一个条件判断,可以知道:i是数组IN[]的小标。
从整个流程图得结构来看,该流程是一个循环处理,循环退出条件是IN[i]=空格,也就是中缀表达式输入完成,循环增量条件是i+i,循环体是从左到右依次输入处理中缀表达式。
对每次输入的中缀表达式的元素分4种情况分别进行处理。 (1) 如果是变量,则将变量保存到输入数组中。 (2) 如果是“(”,则进行A处理,A处理未知。
(3) 如果是“)”,则进行一个循环处理,循环退出条件是栈顶IN[p]=’(’,循环体是B,B处理未知。且B处理在整个流程图中出现3次。
但从循环退出条件可以分析出: A处理一定要将“(”进行入栈操作,因为“(”与“)”必须成对出现,而在处理“)”时,IN栈已经有“(”,所以A处理一定包含“(”元素的入栈操作。
因循环判断条件是IN[p]=’(’,所以可以分析该条件要随着循环的进行而变化,否则有可能进入死循环。而栈的常用操作是入栈、出栈操作,这里很明显应该是出栈操作,所以只可能是p值得改变,也就是B处理中需要栈顶的值的改变。另外,栈顶的值又怎样处理,这里需要结合流程中的其他任务进一步分析。
在退出循环后,直接丢掉栈顶的“)”值,再取下一输入值。 那么目前输入的“)”要进行这样的处理呢?这里根据考题给定的例题,可以知道,将一个中缀表达式转换成后缀表达式后,“(”、“)”均不出现在后缀表达式中,因此可以判断,输入的“)”在处理过程中是要找到匹配的“(”,对中缀表达式“(”、“)”之间的符号进行处理,而对“)”不进行任何处理。 (4) 如果输入的是运算符“*”、“∕”、“+”、“-”,则可能出现两个分支。
第一个分支:p是否为0,也就是栈是否为空,如果为空,则进行A处理,如不为空则进入第二个分支判断处理。
第二个分支:分支条件待确定,根据所给定的信息,可以确定是两个值比较大小,如果是大于则进行A处理,入股哦是小于等于则进行B处理,然后转入分支1的顶部,进入循环处理。
通过对循环体的分析可以得出如下的信息: A处理:含有入栈操作。
B处理:含有出栈操作,栈顶值是丢弃还是进行其他处理待定。
判断条件①:为两个值大小的判断,如果是小于等于,则进行出栈,如果大于等于则进行入栈。
再分析循环退出后的处理流程。
再次进入一个循环,循环条件为栈顶是否为空,如果不为空则进行B处理,也就是出栈操作,将栈中的元素按照后进先出的顺序进行退栈处理,从这里也很难确定B的其他信息。
流程分析完成后,再次分析题目给定的信息。在考题给定的信息中,还有一个优先表在流程中没有使用到,那么这个优先表只可能在流程图中的A、B处理或判断条件①中使用。优先表中的优先关系是运算符的优先关系,且用数值表示,而判断条件①已经分析出是两个值比较大小,因此可以假设判断条件①为判断两个运算符号的优先值。
情况一:中缀表达式的当前元素与后继元素的比较。这种情况的可能性比较小,在流程图中后续元素影响出栈是不合乎逻辑的。
情况二:后缀表达式的当前元素与后续元素的比较。这种情况的可能性比较小,因为当前元素影响写入的情况也不合乎逻辑。
情况三:中缀表达式的但钱元素与栈顶元素比较。这种情况的可能性比较大。 情况四:后缀表达式的当前元素与栈顶元素比较。这种情况的可能性也比较大。
情况五:栈顶元素与其下面在栈元素的比较。这种情况的可能性比较小,比栈内其他元素比较以决定是否出栈是不合乎逻辑的。
根据上面的分析,结合考题给出的例题再次分析,确定假设。 参考答案
【问题1】
PRIOR(IN[i]);PRIOR(S[p]) 【问题2】
功能:将当前符号IN[i]入栈 操作:p+1→p IN[i] →S[p] 【问题3】
功能:出栈(将栈顶元素送往数组POLISH[]) 操作:k+1→k S[p] →POLISH[k] p-1→p 【问题4】
AB+CD*-EF-*G/