pascal中有关栈的问题. pascal栈的问题(前,中,后缀表达式的转换)

作者&投稿:肇凯 (若有异议请与网页底部的电邮联系)
楼上不懂PASCAL不要胡乱复制!!!
简直就是亵渎。。

我还有栈的PPT上课讲义。请将您的邮箱发给我,谢谢。我会发送附件至邮箱。

1 栈的概念及运算

栈的定义:栈是一种特殊的表这种表只在表头进行插入和删除操作。因此,表头对于栈来说具有特殊的意义,称为栈顶。相应地,表尾称为栈底。不含任何元素的栈称为空栈。

栈的逻辑结构:假设一个栈S中的元素为an,an-1,..,a1,则称a1为栈底元素,an为栈顶元 素。栈中的元素按a1 ,a2,..,an-1,an的次序进栈。在任何时候,出栈的元素都是栈顶元素。换句话说,栈的修改是按后进先出的原则进行的,如图1所示。因此,栈又称为后进先出(Last In First Out)表,简称为LIFO表。所以,只要问题满足LIFO原则,就可以使用栈。

栈的运算:为一种抽象数据类型,常用的栈运算有:

运算 含义
inistack(S) 使S成为一个空栈。
getTop(S) 这是一个函数,函数值为S中的栈顶元素。
Pop(S) 从栈S中删除栈顶元素,简称为抛栈。
Push(S,x) 在S的栈顶插入元素x,简称为将元素x入栈。
Empty(S) 这是一个函数。当S为空栈时,函数值为true,否则函数值为false。

2 栈的存储与实现
栈的数组实现:由于栈是一个特殊的表,我们可以用数组来实现栈。考虑到栈运算的特殊性,我们用一个数组elements[1..maxlength]来表示一个栈时,将栈底固定在数组的底部,即elements[1]为最早入栈的元素,并让栈向数组上方(下标增大的方向)扩展。同时,我们用一个游标top来指示当前栈顶元素所在的单元。当top=0时,表示这个栈为一个空栈。在一般情况下,elements中的元素序列elements[top],elements[top-1],..,elements[1]就构成了一个栈。这种结构如图2所示。

图 2

利用上述结构,我们可以形式地定义栈类型TStack如下:

Type

TStack=Record

top:integer;

element:array[1..maxlength] of TElement;

End;

在这种表示法下,栈的5种基本运算可实现如下。

procedure inistack(Var S:TStack);

begin

S.top:=0;

end;

function Empty(var S:Stack):Boolean;

begin

return(S.top=0);

end;

finction Top(var S:TStack):TElement;

begin

if Empty(S) then Error('The stack is empty.')

else return(S.element[S.top]);

end;

procedure Pop(var S:TStack);

begin

if Empty(S) then Error('The stack is empty.')

else dec(S.top); {S.top减1}

end;

procedure Push(var S:TStack;x:TElement;);

begin

if S.top=maxlength then Error('The stack is full.')

else begin

inc(S.top); {S.top增1}

S.elements[S.top]:=x;

end;

end;

以上每种操作的复杂性为O(1)。

在一些问题中,可能需要同时使用多个同类型的栈。为了使每个栈在算法运行过程中不会溢出, 要为每个栈顶置一个较大的栈空间。这样做往往造成空间的浪费。实际上,在算法运行的过程中,各个栈一般不会同时满,很可能有的满而有的空。因此,如果我们让多个栈共享同一个数组,动态地互相调剂,将会提高空间的利用率,并减少发生栈上溢的可能性。 假设我们让程序中的两个栈共享一个数组S[1..n]。利用栈底位置不变的特性,我们可以将两个栈的栈底分别设在数组S的两端,然后各自向中间伸展,如图3所示。这两个S栈的栈顶初值分别为0和n+1。只有当两个栈的栈顶相遇时才可能发生上溢。由于两个栈之间可以余缺互补,因此每个栈实际可用的最大空间往往大于n/2。

3 栈的应用

1.表达式的求值

问题:能否设计算法,编制一个程序,让计算机扫描如下表达式,并将其值打印出来。
# 3 * ( 4 + 8 ) / 2 -5 #
注:给表达式设置#,标志扫描的开始和结束。
提示算法:设两个栈,一个是操作数栈,用来存放操作数,如3、4、8等,另一个是运算符栈,用来存放运算符。
首先将标志“#”进运算符栈的栈底。
然后依次扫描,按照栈的后进先出原则进行:
(1)遇到操作数,进操作数栈;
(2)遇到运算符时,则需将此运算符的优先级与栈顶运算符的优先级比较,
若若高于栈顶元素则进栈,继续扫描下一符号,
否则,将运算符栈的栈顶元素退栈,形成一个操作码Q,同时操作数栈的栈顶元素两次退栈,形成两个操作数a、b,让计算机对操作数与操作码完成一次运算操作,即aQb,并将其运算结果存放在操作数栈中……

模拟计算机处理算术表达式过程。从键盘上输入算术表达式串(只含+、-、×、÷运算符,充许含括号),输出算术表达式的值。设输入的表达式串是合法的。

附源程序:

program exsj_1;
const
max=100;
var
number:array[0..max] of integer;
symbol:array[1..max] of char;
s,t:string;
i,p,j,code:integer;
procedure push;{算符入栈运算}
begin
inc(p);symbol[p]:=s[i];
end;

procedure pop;{运算符栈顶元素出栈,并取出操作数栈元素完成相应的运算}
begin
dec(p);
case symbol[p+1] of
'+':inc(number[p],number[p+1]);
'-':dec(number[p],number[p+1]);
'*':number[p]:=number[p]*number[p+1];
'/':number[p]:=number[p] div number[p+1];
end;
end;

function can:boolean;{判断运算符的优先级别,建立标志函数}
begin
can:=true;
if (s[i] in ['+','-']) and (symbol[p]<>'(') then exit;
if (s[i] in ['*','/']) and (symbol[p] in ['*','/']) then exit;
can:=false;
end;

begin
write('String : '); readln(s); s:='('+s+')'; i:=1; p:=0;
while i<=length(s) do
begin
while s[i]='(' do {左括号处理]
begin
push; inc(i);
end;
j:=i;
repeat {取数入操作数栈}
inc(i);
until (s[i]<'0') or (s[i]>'9');
t:=copy(s,j,i-j); val(t,number[p],code);
repeat
if s[i]=')' then {右括号处理}
begin
while symbol[p]<>'(' do pop;
dec(p); number[p]:=number[p+1];
end
else
begin {根据标志函数值作运算符入栈或出栈运算处理}
while can do pop;
push;
end;
inc(i);
until (i>length(s)) or (s[i-1]<>')');
end;
write('Result=',number[0]);
readln;
end.

2.背包问题

问题:假设有n件质量分配为w1,w2,...,wn的物品和一个最多能装载总质量为T的背包,能否从这n件物品中选择若干件物品装入背包,使得被选物品的总质量恰好等于背包所能装载的最大质量,即wi1+wi2+...+wik=T。若能,则背包问题有解,否则无解。
算法思想:首先将n件物品排成一列,依次选取;若装入某件物品后,背包内物品的总质量不超过背包最大装载质量时,则装入(进栈);否则放弃这件物品的选择,选择下一件物品试探,直至装入的物品总和正好是背包的最大转载质量为止。这时我们称背包装满。
若装入若干物品的背包没有满,而且又无其他物品可以选入背包,说明已装入背包的物品中有不合格者,需从背包中取出最后装入的物品(退栈),然后在未装入的物品中挑选,重复此过程,直至装满背包(有解),或无物品可选(无解)为止。
具体实现:设用数组weight[1..N],stack[1,N]分别存放物品重量和已经装入背包(栈)的物品序号,MaxW表示背包的最大装载量。每进栈一个物品,就从MaxW中减去该物品的质量,设i为待选物品序号,若MaxW-weight[i]>=0,则该物品可选;若MaxW-weight[i] < 0,则该物品不可选,且若i>n,则需退栈,若此时栈空,则说明无解。
用Pascal实现的参考函数:

Function knapstack(n,MaxW,weight);
begin
top:=0; i:=1; {i为待选物品序号}
while (MaxW>0) and ( i < = n ) do
begin
if (MaxW-weight[i]>=0) and ( i < = n ) then
begin top:=top+1; stack[top]:=i;MaxW=MaxW-weight[i] end;
{第i件物品装入背包}
if MaxW=0 then return(true)
else begin
if (i=n) and (top>0) then {背包内有不合适物品}
begin {取栈顶物品,恢复MaxW的值}
i:=stack[top]; top:=top-1;MaxW=MaxW+weight[i];
if top>0 then begin
i:=stack[top]; top:=top-1;MaxW=MaxW+weight[i];
end;
end;
i:=i+1;
end;
end;
return(false) {问题无解}
end;

练习:完整完成背包问题

1.算术函数
函数标识符 自变量类型 意义 结果类型
abs 整型、实型 绝对值 同自变量
arctan 整型、实型 反正切 实型
cos 整型、实型 余弦 实型
exp 整型、实型 指数 实型
frac 整型、实型 小数部分 实型
int 整型、实型 整数部分 实型
ln 整型、实型 自然对数 实型
pi 无自变量 圆周率 实型
sin 整型、实型 正弦 实型
sqr 整型、实型 平方 同自变量
sqrt 整型、实型 平方根 实型
例:abs(-4)=4 abs(-7.49)=7.49 arctan(0)=0.0
sin(pi)=0.0 cos(pi)=-1.0 frac(-3.71)=-0.71
int(-3.71)=-3.0 sqr(4)=16 sqrt(4)=2

2.标准函数
函数标识符 自变量类型 意义 结果类型
odd 整型 判断奇数 布尔型
pred 离散类型 求前趋 同自变量
succ 离散类型 求后继 同自变量
例:odd(1000)=false pred(2000)=1999 succ(2000)=2001
odd(3)=true pred('x')='w succ('x')='y'

3.转换函数
函数标识符 自变量类型 意义 结果类型
chr byte 自变量对应的字符 字符型
ord 离散类型 自变量对应的序号 longint
round 实型 四舍五入 longint
trunc 实型 截断取整 longint
例:chr(66)='B' ord('A')=65 round(-4.3)=-5 trunc(2.88)=2

4.杂类函数
函数标识符 自变量类型 意义 结果类型
random 无自变量 [0,1间的随机实数 real
random word [0,自变量间的随机整数) word
randomize 无自变量 初始化内部随机数产生器 longint
upcase 字符型 使小写英文字母变为大写 字符型
downcase 字符型 使小写英文字母变为大写 字符型

SYSTEM TP的运行库,包括常用的标准函数和过程,可以在程序中直接使用,不需USES语句说明。
DOS 具有日期、时间、目录查找、程序执行等功能
CRT 具有屏幕模式控制、扩展键盘码、颜色、窗口、声音等 功能
PRINTER 支持打印输出操作。
GRAPH 高级图形软件包,支持多种图形适配器。
GRAPH3 实现TP3.0的图形软件包。
TURBO3 兼容TP3.0的源程序。
OVERLAY 实现高级覆盖管理

SYSTEM单元常用过程与函数
ABS(X) F 求变量的绝对值
ADDR(X) F 测变量地址
APPEND(F) P 打开一个存在的文本文件,并将文件指 针指向文件末尾准备添加元素
ARCTAN(X) F 反正切
ASSIGN(F,C) P 将字符串C所表示的外部文件名赋给文 件变量F
ASSIGNED(X) P 测试程序当中的指针或变量是否为空
BLOCKREAD(F,D,NUM) P 读类型文件。
BLOCKWRITE(F,D,NUM) P 写无类型文件
BREAK P 中止或结束循环
CHDIR(PATH) P 改变当前目录
CHR(X) F 求ASCII码值为X的字符
CLOSE(F) P 关闭文件
CONCAT(S1,S2...S3) F 字符串合并
CONTINUE P 继续循环
COPY(S,POS,LEN) F 返回一个字符串的子串
COS(X) F 余弦函数
CSEG F 返回CS寄存器的当前值
DEC(X) F X:=X-1
DELETE(S,POS,LEN) P 删除一个字符串的子串
DISPOSE(P) P 释放一个动态变量
DSEG F 返回DS寄存器的当前值
EOF(F) F 判断文件是否结束
EOLN(F) F 判断文件类型中的一行是否结束
ERASE(F) P 删除一个存在的外部文件。
EXIT P 过程中止
EXP(X) F 以E为底的指数函数
FILEPOS(F) F 文件记录的当前位置
FILESIZE(F) F 文件记录数
FILLCHAR(D,LEN,DATE) P 填充数值或字符
FLUSH(F) P 清空文件缓存区
FRAC(X) F 取实形变量的小数部分
FREEMEM(P,I) P 释放变长动态变量
GETDIR(DRV,PATH) P 取当前盘,当前目录
GETMEM(P,I) P 分配变长的动态变量,并把块地址存放在一个指针变量中
HALT P 立即中止程序执行,返回TP编辑器或DOS
HI(I) F 返回一个变量的高位字节
INSERT(S,D,POS) F 在一个字符串中某一位置开始插入一个子串
INT F 取整数部分
IORESULT F 返回最后一次输入/出操作的结果状态
LENGTH(S) F 取字符串的长度
LN(R) F 求自然对数
LO(I) F 返回一个变量的低位字节
MAXAVAIL F 返回最大内存空间
MEMAVAIL F 返回可用内存数目
MKDIR(PATH) P 建立一个子目录
MOVE(S,D,LEN) P 快传送
NEW(P) P 建立一个新的动态变量
ODD(X) F 判断一个变量的值是否为奇数
OFS(X) F 侧变量偏移地址
ORD(CH) F 求一个字符的ASCII码值
PARAMCOUNT F DOS参数串长度
PARAMSTR(N) F DOS参数串
PI F 圆周率的值
pos(str1,str2) f 测一个字符串中包含的另一个子串的开始位置
pred(x) f 求前驱
ptr(i) f 指针赋值
random f 返回0~1之间的随机实数
randomize p 初始化随机数发生器
read/readln(f,x) p 读入/输入数据
rename(f,str) p 给一个外部文件改名
reset(f) p 打开文件,并将文件指针指向开始,并准备读数据
rewrite(f) p 打开文件,并将文件指针指向开始,准备写资料
rmdir(path) p 删除一个子目录
round(x) f 求实数的近似数
runerror p 停止程序的运行
scrollto p 滚动显示窗口的某部分内容
seek(f,n) p 将文件指针定位于文件f的第n个文件成分上
seekrof(f) f 定位到文件尾
seekroln(f) f 定位到行尾
seg(n) f 测变量段地址
settextbuf(f) p 将输入/出缓冲区与一个文本文件建立关联
sin(x) f 正弦函数
sizeof(x) f 测变量大小
sptr f 返回sp寄存器的当前值
sqr(x) f 平方
sqrt(x) f 平方根
sseg f 返回ss寄存器的当前值
str(i,s) f 将一个整数转换成字符串
succ(X) f 后继函数
swap(x) f 交换一个变量的高位和低位字节
trunc(x) f 截去实数的小数部分
truncate(f) p 截去文件当前指针以后的内容
upcase(ch) f 将小写字母转换成大写字母
val(s,r,p) p 将一个字符串转换成数值
writeln(f,x) p 输出
dos单元常用过程与函数
getdate p 返回系统当前日期
detftime p 返回最后一次写入的日期和时间
gettime p 返回系统当前时间
packtime p 转换系统日期和时间,封装成4个字节的长整形格式
setdate p 设置系统当前日期
setftime p 写入新的系统日期和时间,覆盖系统最后一次写入的 系统日期和时间文件
settime p 设置系统当前时间
uppacktime p 将系统日期和时间转换成纪录格式
diskfree f 返回指定磁盘可用剩余空间
disksize f 返回指定磁盘的总容量
get/setverity p 返回/设置dos状态下的磁盘读写标记
fexpand f 返回函数名的全称
fsearch f 在一个目录中查找文件
fsplit f 将一个文件名分成目录、文件名、扩展名
findfirst p 在当前目录或指定目录下查找第一个与给定属性相匹 配的文件名

3 turbo pascal基本函数过程及解释
findnext p 返回下一个满足匹配条件的文件名
getfattr p 返回文件的属性
setfattr p 设置文件属性
gerintvec p 返回某个中断变量值
intr p 执行软中断
msdos p 执行dos 系统调用
setintvec p 设定中断值
exec p 通过一个特定命令行执行特定程序段
keep p 中断程序的执行但仍驻留在内存中
swapvectors p 用当前变量交换所有中断变量值
dosexitcode f 回到子程序出口
dosversion f 显示dos版本
crt单元
assigncrt(f) p 将文本文件f与显示器crt建立联系
clreol p 清除当前行光标所在位置以后的字符
clrscr p 清除当前窗口或屏幕,光标返回到左上角
delay(t) p 等待t毫秒
delline p 清除光标所在行上所有内容
gotoxy(x,y) p 将光标移到屏幕某处
highvideo p 选择高亮度显示字符
insline p 在当前光标位置插入空行
keypressed f 测定键盘输入状态
lowvideo p 低亮度显示字符
normvideo p 选择正常文本属性从光标所在位置开始显示字符
nosound p 关闭内部扬声器
readkey p 等待从键盘输入一个字符
sound(hz) p 以hz指定的频率发声
textbackground(soor) p 设置正文背景颜色
textcolor(color) p 设置正文前景颜色
textmode p 选择特定的文本显示模式
wherex/y f 返回当前光标位置的坐标值
window(x1,y1,x2,y2) p 在屏幕定义一个文本窗口

其他单元
chain(f) p 目标程序链接
execute(f) p 执行目标程序
mark(p) p 标记动态变量
release(p) p 释放动态变量区
srtinit p 屏幕初始化
crtline p 汉字屏幕方式转换
graphbackground(color) p 选择背景色
graphcolormode p 中分辨率彩色图形方式,320*200彩色
graphmode p 中分辨率黑白图形方式,320*200黑白
graphwindow(x1,y1,x2,y2,color)p 定义图形方式窗口
hires p 高分辨率单色图形方式,640*200黑白
hirescolor(color) p 高分辨率彩色图形方式,640*200彩色
palette(color) p 中分辨率彩色图形颜色组
ovrpath(path) p 指定覆盖文件路径
draw(x1,y1,x2,y2,color) p 画线
intr(n,m) p 8086中断调用
plot(x,y,color) p 画点
random(integer) f 产生随机整数
seg(x) f 测变量段地址
colortable(c1,c2,c3,c4) p 重定义颜色组
arc(x,y,radius,color) p 画圆弧
circle(x,y,radius,color) p 画圆
getpic(buffer,x1,x2,y1,y2) p 屏幕转储到屏幕
putpic(buffer,x,y) p 缓冲器转储到屏幕
getdotcolor(x,y) p 读点
fillscreen(color) p 填充屏幕
fillshape(x,y,fillcol,bordercol) p 填充一个区域

常用数学函数
求绝对值函数abs(x)
定义:function Abs(X): (Same type as parameter);
说明:X可以是整型,也可以是实型;返回值和X的类型一致例子:

取整函数int(x)
定义:function Int(X: Real): Real;

注意:X是实型数,返回值也是实型的;返回的是X的整数部分,也就是说,X被截尾了(而不是四舍五入)例子:
var R: Real;
begin
R := Int(123.567); { 123.0 }
R := Int(-123.456); { -123.0 }
end.

截尾函数trunc(x)
定义:function Trunc(X: Real): Longint;

注意:X是实型表达式. Trunc 返回Longint型的X的整数部分例子:
begin
Writeln(1.4, ' becomes ', Trunc(1.4)); { 1 }
Writeln(1.5, ' becomes ', Trunc(1.5)); { 1 }
Writeln(-1.4, 'becomes ', Trunc(-1.4)); { -1 }
Writeln(-1.5, 'becomes ', Trunc(-1.5)); { -1 }
end.

四舍五入函数round(x)
定义:function Round(X: Real): Longint;

注意:X是实型表达式. Round 返回Longint型的X的四舍五入值.如果返回值超出了Longint的表示范围,则出错. 例子:
begin
Writeln(1.4, ' rounds to ', Round(1.4)); { 1 }
Writeln(1.5, ' rounds to ', Round(1.5)); { 2 }
Writeln(-1.4, 'rounds to ', Round(-1.4));{ -1 }
Writeln(-1.5, 'rounds to ', Round(-1.5));{ -2 }
end.

取小数函数frac(x)
定义:function Frac(X: Real): Real;

注意:X 是实型表达式. 结果返回 X 的小数部分; 也就是说,Frac(X) = X - Int(_X). 例子:
var
R: Real;
begin
R := Frac(123.456); { 0.456 }
R := Frac(-123.456); { -0.456 }
end.

求平方根函数sqrt(x)和平方函数sqr(x)
定义:平方根:function Sqrt(X: Real): Real;
注意:X 是实型表达式. 返回实型的X的平方根. 平方:function Sqr(X): (Same type as parameter);
注意:X 是实型或整型表达式.返回值的类型和X的类型一致,大小是X的平方,即X*X.
例子:
begin
Writeln('5 squared is ', Sqr(5)); { 25 }
Writeln('The square root of 2 is ',Sqrt(2.0)); { 1.414 }

pascal 关于出栈序列~

希望采纳,多谢
这个根本不是组合数,是catalan数,因为栈空时不能出栈
我有一个递归的算法;总之就是每一层先判断能否出栈,能就先出,然后递归下一层;再判断能否进栈,能就进,递归下一层;
var
n:integer;
a:array[0..100] of integer;
procedure go(x,y:integer;s:string);(x是已进栈的个数,y是已出栈的个数,s是目前的出栈排列)
var
k:integer;
begin
if (x=n) and (y=n)then write(s)(当全进全出就输出排列并把剩下的出栈)
else begin
if y<x then(能出就出)
begin
k:=a[a[0]];(k用来暂存出栈的元素,因为递归后要恢复)
dec(a[a[0]]);(a[0]是a里元素个数)
go(x,y+1,s+chr(k+48));(递归)
inc(a[a[0]]);
a[a[0]]:=k;(这两句是恢复语句,因为搜索只是一种假设,搜完要把动了的东西重新放好)
end;
(进栈)
if x<n then begin
inc(a[0]);
a[a[0]]:=x+1;
go(x+1,y,s);
dec(a[0]);(这里不必把原来最后一格清零,因为a[i]是否有意义取决于a[0]够不够i大)
end;
end;
end;
begin
readln(n);
fillchar(a,sizeof(a),0);(快速清零)
go(0,0,'');(搜索)
end.
这个方法可能还可以优化,但是我都有点忘了

栈是一种特殊的线性表,是一种只允许在表的一端进行插入或删除操作的线性表。表中允许进行插入、删除操作的一端称为栈顶。表的另一端称为栈底。栈顶的当前位置是动态的,对栈顶当前位置的标记称为栈顶指针。当栈中没有数据元素时,称之为空栈。栈的插入操作通常称为进栈或入栈,栈的删除操作通常称为退栈或出栈。
在生活中常见到这样的例子:假设餐厅里有一叠盘子,如果要从中拿取盘子,只能从最上面一个开始拿,当要再放上一个盘子时也只能放在最上面。栈的结构正是如此。根据栈的定义,每次进栈的数据元素都放在原当前栈顶元素之前而成为新的栈顶元素,每次退栈的数据元素都是原当前栈顶元素。这样,最后进入栈的数据元素总是最先退出栈,因此,栈具有“后进先出”(LIFO:First In Last Out)的特性。
图5.8是一个栈的动态示意图,图中箭头代表当前栈顶指针位置。图5.8(a)表示一个空栈;图5.8(b)表示插入一个数据元素 A以后的状态;图5.8(c)表示插入数据元素 B、C以后的状态;图5.8(d)表示删除数据元素C以后的状态;图5.8(e)表示删除数据元素 B、A以后的状态。简言之,若进栈顺序为A、B、C,则退栈顺序为C、B、A。图5.8显示的是一个顺序存储结构的栈,栈也可以用链式存储结构存储。

图5.8栈的动态示意图

栈的应用非常广泛,表达式求值、递归过程实现都是栈应用的典型例子。下面简单讨论一下高级语言中的表达式处理是怎样通过栈实现的。
在用高级语言编写程序时,经常写出各种类型的表达式:算术表达式、关系表达式和逻辑表达式等等。编译系统在处理表达式时,需要将表达式翻译成机器指令序列,这首先需要确定运算次序。为此,需要建立两个栈——操作数栈(ODS)和操作符栈(OPS),然后自左至右扫描表达式。为叙述简洁,仅讨论算术表达式的计算,且假设表达式中只含有加、减、乘、除四种运算符和左、右圆括号,一个表达式用“#”作为分界符标识表达式的结束,并将表达式中自左至右所读到的一个操作数或一个操作符称为“一个词”。用栈实现表达式求值的处理过程如下:
(1) 读入一个词;
(2) 判断该词是操作数还是操作符,如果是操作数,则将该操作数压入ODS栈并转第(1)步;否则继续往下;
(3) 判断表达式是否结束,是结束符则转第(7)步,否则继续往下;
(4) 判断当前操作符优先级是否大于或等于OPS栈顶操作符的优先级(左括号的优先级最高,其次是乘除,再是加减,右括号的优先级最低)或者OPS栈是否为空,如果是,当前操作符压入OPS栈并转第(1)步;否则,继续往下;
(5) 从ODS栈中弹出两个操作数Y和X,从OPS栈中弹出一个操作符θ,进行运算XθY,并将结果压入ODS栈。需要说明的是,如果当前操作符是右括号,则重复第(5)步这一过程,直到OPS栈顶操作符为左括号;
(6) 当前操作符压入OPS栈(如果当前操作符是右括号,则它不但不压入OPS栈中,相反还从OPS栈中弹出左括号,这称为去括号)后,转第(1)步;
(7) 判断OPS栈是否为空,不是,则从ODS栈中弹出两个操作数Y和X,从OPS栈中弹出一个操作符θ,进行运算XθY,并将结果压入ODS栈;
(8) ODS栈顶的值即为所求表达式的值,求值过程结束。
利用栈处理算术表达式a×(b-d/e)+f的过程如下图5.9所示。
图5.9(a)表示了依次读入表达式中的“a”、“*”、“(”、“b”、“-”、“d”、“/”、“e”等单词后操作数栈ODS(图示的左边)和操作符栈OPS(图示的右边)的状态;图5.9(b)和图5.9(c)表示了读入“)”后,去括号的过程,其中t1=d/e,t2=b-t1;图5.9(d)表示了读入“+”后,ODS和OPS的状态,其中t3=a*t2;图5.9(e)表示了读入“f”后,ODS和OPS的状态;图5.9(f)表示了读入表达式结束符后,ODS和OPS的状态,其中t4=t3+f,此时操作符栈OPS为空,操作数栈ODS的栈顶元素t4就是所求的表达式的值。



图5.9利用栈处理表达式a*(b-d/e)+f的示意图

设有一个空栈,栈顶指针为1000H(十六进制),现有输入序列为1,2,3,4...
答:pop出栈:栈中是1,输出2 push进栈:栈中1,3 pop出栈:栈中1,输出3 然后push:栈中1,4 最后push:栈中1,4,5 所以输出的是2,3 1、线性的栈,数组形式:动态申请的数组,栈顶指针可以是一个整数(下标),空栈时为-1,非空栈时为数组对应的下标。2、链表式:空栈时栈顶指针可以是...

数据结构问题,为什么栈会出现下溢现象?栈中元素删除后栈顶指针减1,怎...
答:堆栈只有一个元素的时候,当栈顶元素出栈时,P指针下移,但是已经到栈低了,再下移就一出去了。如果不判断就是会出现下溢。

关于堆栈的问题:在c语言中,由于把a变量压入堆栈,top弹出堆栈的时候,弹...
答:1. 首先一点你要明白的是,栈中保存的是值,也就是a入栈,是把a的值放到栈中,栈不会记得这个值是a的。2. C语言中,我们使用栈从来都只是为了保存一个值而已,并不关心这个值是谁的。你想想看,你使用栈的过程中有去关心过每个入栈的值的来源吗?栈只是简单的数据堆放的仓库而已,不过是进进...

请各位走过路过的朋友帮帮忙啊!急需2011年四川计算机二级C语言考试试题...
答:(1)下列关于栈叙述正确的是 A)栈顶元素最先能被删除 B)栈顶元素最后才能被删除 C)栈底元素永远不能被删除 D)以上三种说法都不对 (2)下列叙述中正确的是 A)有一个以上根结点的数据结构不一定是非线性结构 B)只有一个根结点的数据结构不一定是线性结构 C)循环链表是非线性结构 D)双向链表是非线性结构 (...

单片机简单的堆栈问题
答:如果字面理解‘指向’,那当然是指向栈底,因为无论数据是多少,记录规则如何,总是为了确定栈底在什么位置,当全部弹出,此时指向必定是栈底 如果‘指向’的含义是此时SP的数据值,那就是D C是肯定不对的 堆栈 程序的堆栈可以位于 256 字节数据存储器中的任何位置。堆栈区域用堆栈指针(SP,0x81)...

设有四个元素1、2、3、4依次进入一个栈中,则可能得到(1)种出栈序列,不...
答:有个东西叫Catalan数,可以计算出所有出栈情况个数 设入栈序列为I(n):12...n,则I(n)有C(2nn)-C(2nn-1)个出栈序列。这个有点难,一定不是A D 答案在BC中,只要能找出7种以上的不可能,就可以确定是B 1234全排列共24种 4先出栈的 只有4321是合理的,其余都不可能,共有5种 3先出栈...

【C语音菜鸟】关于栈程序的一个小问题
答:实际上如你所说,在栈底有一个没用到的空节点,就是初始化时候创建的那个,但pS->Top却没有指向该节点,而是赋值为NULL,实际导致此节点没有加入到栈的计算中来,也就是你循环遍历中,使用while (p !=NULL)的原因。而你所说的while(p !=pS->Bottom)有相同的运算结果,我觉得不太可能。因为...

pascal中有关栈的问题.
答:栈中的元素按a1 ,a2,..,an-1,an的次序进栈。在任何时候,出栈的元素都是栈顶元素。换句话说,栈的修改是按后进先出的原则进行的,如图1所示。因此,栈又称为后进先出(Last In First Out)表,简称为LIFO表。所以,只要问题满足LIFO原则,就可以使用栈。 栈的运算:为一种抽象数据类型,常用的栈运算有:运算 含义...

C语言栈和队列问题:停车场停车问题
答:// 等候队列typedef struct{ int count; // 用来指示队中的数据个数 Car Pave[MAX_PAVE-1]; // 各汽车信息的存储空间 int front, rear; // 用来指示队头和队尾位置的静态指针}Pavement;// 让路栈typedef struct{ Car Help[MAX_STOP-1]; // 各汽车信息的存储空间 ...

关于栈的问题
答:A答案的顺序:6进 5进 5出 4进 4出 3进 3出 6出 2进 1进 1出 2出 B的:6进 5进 4进 4出 5出 3进 3出 2进 1进 1出 2出 6出 C的:6进 5进 4进 3进 应该是4先出,所以错了。D的:6进 5进 4进 3进 2进 2出 3出 4出 1进 1出 5出 6出 ...