
本程序实现了基于堆栈的字符串中括号配对检查功能。在本程序中,使用栈这种数据结构来检查输入的字符串中的括号是否配对。如果括号配对,则输出“括号配对成功”,否则输出“括号配对失败”。
程序实现
程序实现的思路如下:
定义一个栈(使用list数据类型实现),用于存储左括号。
遍历输入的字符串中的每个字符。对于每个字符:
如果是左括号,则将其压入栈中。
如果是右括号,则d出栈顶元素,判断其是否是对应的左括号。如果是,则继续遍历字符串,否则输出“括号配对失败”。
如果遍历完字符串后栈不为空,则输出“括号配对失败”,否则输出“括号配对成功”。
程序实现的Python代码如下:
def check_brackets(input_str):stack = []
for char in input_str:
if char == '(' or char == '{' or char == '[':
stackappend(char)
elif char == ')' or char == '}' or char == ']':
if not stack:
return "括号配对失败"
top = stackpop()
if (top == '(' and char == ')') or (top == '{' and char == '}') or (top == '[' and char == ']'):
continue
else:
return "括号配对失败"
if not stack:
return "括号配对成功"
else:
return "括号配对失败"
使用方法
将上述代码复制到Python环境中。
调用check_brackets函数,并传入需要检查的字符串作为参数。
程序将输出“括号配对成功”或“括号配对失败”。
例如:
input_str = "({[()]})"result = check_brackets(input_str)
print(result)
输出结果为“括号配对成功”。
在计算机领域,堆栈是一个不容忽视的概念,但是很多人甚至是计算机专业的人也没有明确堆栈其实是两种数据结构。
堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。
要点:
堆:顺序随意
栈:后进先出(Last-In/First-Out)详细资料:
>
堆栈其实是两种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端
(称为栈顶(top))
对数据项进行插入和删除。要点:堆,顺序随意。栈,后进先出(Last-In/First-Out)。
针对栈这种数据结构的基本 *** 作有两种:压栈和d出,
在栈帧中包含两个标志----栈底和栈顶,其中栈顶标识着要push或pop
的数据的地址,而栈底则表示栈帧中最后一个数据的内存地址。
在Win32中,寄存器esp存放着栈底指针,栈是向低地址方向生长,
因此esp指向栈顶元素
堆栈对比( *** 作系统):
由编译器自动分配释放,存放函数的参数值,局部变量的值等。其
*** 作方式类似于数据结构中的栈栈使用的是一级缓存,
通常都是被调用时处于存储空间中,调用完毕立即释放
堆( *** 作系统):
一般由程序员分配释放,
若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些
堆(数据结构)
:堆可以被看成是一棵树,如:堆排序
栈(数据结构)
:一种后进先出的的数据结构
具体不同语言有不同的描述,可查看各种语言的api
int Pop(char &c) ----> 这里加了& 引用类型, 这样pop出来的数据才能返回,(传参副本问题)
while(!csEmpty())--->加了个! , 不空的时候才能pop,写反了
另:
csPush((char)i+'0');--->1改成了'0' 这样输出的是可见的字符,好看
;已知 (A) = 02H, (SP) = 40H, (41H) = FFH, (42H) = FFH
;这是一个子程序,调用时PC由硬件自动入栈,所以调用后SP = 40H+2 = 42H,而42H处值=FFH
POP DPH ;出栈,栈数据放到DPH和DPL,这时DPTR = FFFFH
POP DPL ;因为开始SP =42H,出栈后SP = 42H - 2 = 40H
MOV DPTR,#3000H ;向寄存器DPTR写入数据3000H
RR A ;A右移一次,A=02H=0000 0010 -->0000 0001=01H
MOV B,A ;B = A = 01H
MOVC A,@A+DPTR ;将ROM地址 A+DPTR = 01H+3000H = 3001H 处的数据读到A中
PUSH ACC ;将 读到的数据 推入栈,看数据区3001H处 = 10H
;入栈是先SP+1,再读入数据,所以(41H) = 10H,SP = 41H
MOV A,B ;A = B = 01H
INC A ;A = 01H+1 = 02H
MOVC A,@A+DPTR ;读取ROM 3002H地址单元的内容:80H
PUSH ACC ;将 读到的数据 推入栈,这时(42H) = 80H,SP = 40H
RET ;返回时,PC由硬件出栈,因为这时SP已经不是42H,而且程序一开始
;就执行POP导致PC入栈值读出来,然后经过MOV DPTR,#3000H语句就丢失掉了,程序可能回不到
;调用前的地方,而是跑到 读取到的数据 1080H这个地方了,所以执行完后PC = 1080H
;--数据地址区----------
ORG 3000H
DB 10H,80H,30H,50H,30H,50H
因为CPU要使用堆栈,主要是子程序调用call和ret指令,使用堆栈来存储返回地址,调用子程序的时候,后调用的子程序先返回,而且还可能嵌套调用甚至递归调用,所以必须使用先进后出的数据结构stack来实现返回地址的存储。
没有堆栈stack,就无法实现函数/子程序调用,
还有高级语言都用stack来存储局部变量和参数,汇编也可以用,但是比较麻烦。汇编经常使用stack来保存寄存器的值,PUSH和POP指令比较好用
嗯,你没有切换堆栈段,是无法回到程序原位置处的,例如:
call mymain
mov ax, 1
mymain:
push ax
push ax
ret
这样程序是不能返回原点的。因为子程序使用的堆栈是主程序的,在主程序调用子程序是保存的断点信息被你在子程序中push掉了(sp的值被你修改了),所以无法正确执行。
从中可以看出不足处: 子程序用的是主程序的堆栈段,容易修改主程序的数据。可以在调用子程序时为子程序切换堆栈段使子程序使用自己的堆栈段,在子程序返回时还原主程序的堆栈(当然用相应的算法写个子程序来处理这个问题,可以使子程序自动还原主程序的堆栈。可以讨论一下)例:
mov ax,ss ;首先用ax,bx保存ss,sp的值。这样就不担心主程序的堆栈段了
mov bx,sp
;(如果在调用子程序中要改变ax和bx的值时,在调用保存这个值,这个就是主程序的堆栈段了,下面例中没有改变值,所以不保存了)
call mymain
mov ax,1
;
mymain:
mov cx,0x7d00 ; (子程序使用新的堆栈段)
mov sp,cx
push cx ;改变了子程序的堆栈段,而没改变主程序的堆栈段
push cx
;子程序完成后恢复主程序的堆栈段,注意在调用子程序前sp的值以改变,在子程序中要使sp值减2
sub bx,2
mov sp,bx
mov ss,ax ;恢复主程序的堆栈段
ret ;使用主程序的堆栈段返回主程序
这样做虽然复杂了许多,但子程序使用了自己的堆栈段后不用关心主程序的堆栈是否受到影响。明白了吗?在没用 *** 作系统的介入下(调用什么系统功能呀)在程序消亡前所有的东西都是你自己在控制,这就是汇编。
在这里我想说一下自己的想法,我还没时间去实现(上班苦呀)你可以参考一下(这只是大体想法,有不足处自己修改):
我们可以几个子程序段来实现:
首先可以写个子程序用来切换主程序的堆栈,当然可以在主程序中定义保存相关数据的结构。这里注意这个代码段本身是个子程序调用,在切换段时要注意把返回点从主程序的堆栈段中复制到新段中,同时把主程序的堆栈段的相关信息写到数据结构中去。然后用新的堆栈段就可以返回到主程序中。这样这个切换堆栈子程序就差不多了。
接下来写个还原堆栈子程序段,记住在调用这个子程序段是,我们还在目标子程序中执行代码,所以我们要从数据结构中读取数据还原主程序的堆栈段。
堆栈其实是数据结果中的两个概念 ,是存放数据的方式,堆:顺序随意;栈:后进先出(Last-In/First-Out)。要说用处,那就是在写代码的时候,有时数据存取肯定是要有规定的顺序的,这个是你自己规定的,然后按照你所写程序的用处的特点来用堆还是栈还是队列之类的顺序 追问: 程序设计时,为什么要对堆栈指针SP重新赋值? 回答: 这不是初始化嘛
堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。它的特点是按照先进后出的原则存取数据,这里的进与出是指进栈与出栈 *** 作。
80C51片内RAM的部分单元可以用做堆栈。有一个8位的堆栈指针寄存器SP,专用于指出当前堆栈顶部是片内RAM的哪一个单元。80C51单片机系统复位后SP的初值为07H,也就是将从内部RAM的08H单元开始堆放信息。
但是,80C51系列的栈区不是固定的,只要通过软件改变SP寄存器的值便可更动栈区。为了避开工作寄存器区和位寻址区,SP的初值可置为2FH或更大的地址值。如果CPU在 *** 作中要使用两组工作寄存器,如果不使用位变量,SP的初值至少应为0FH或更大的值;如果使用位变量,SP的初值至少应为2FH或更大的值;KeilC51编译器会自动计算SP的初始设定值,无需编程者关心。
以上就是关于数据结构创建工程根据堆栈编写一个程序,检查字符串中括号的配对全部的内容,包括:数据结构创建工程根据堆栈编写一个程序,检查字符串中括号的配对、在程序运行过程中,堆和栈的作用是什么、简述什么是堆栈,以及堆栈中入栈,出栈的过程等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)