栈:后进先出 有栈顶元素无栈低元素 要么头添加头删除要么尾添加尾删除
栈的实际应用:1.括号匹配问题 2.递归
括号匹配:
题目描述:
在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$"标注,不能匹配的右括号用"?"标注.
输入:
输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100。
注意:cin.getline(str,100)最多只能输入99个字符!
输出:
对每组输出数据,输出两行,第一行包含原始输入字符,第二行由"$","?"和空格组成,"$"和"?"表示与之对应的左括号和右括号不能匹配
#include <iostream> #include<stdio.h> #include<stack> using namespace std; stack<int> S; char str[110]; char ans[110]; int main() { while(scanf("%s",str)!=EOF) { int i; for(i=0;str[i]!=0;i++) { if(str[i]=='(') { S.push(i); ans[i]=' '; }else if(str[i]==')') { if(S.empty()==false) { S.pop(); ans[i]=' '; }else ans[i]='?'; }else ans[i]=' '; } while(!S.empty()) { ans[S.top()]='$'; S.pop(); } ans[i]=0; puts(str); puts(ans); } return 0; }
斐波那契:
F(1)=1; F(2)=1; F(n)=F(n-1)+F(n-2)
用栈实现:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#define OK 1
#define ERROR 0
#define MAXSIZE 20
typedef int SElemType;
typedef int Status;
typedef struct
{
SElemType data[MAXSIZE];
int top; //用于栈顶指针
}Sqstack;
//顺序栈的初始化
Status InitSqstack(Sqstack * S)
{
S->top=-1;
return OK;
}
//输出
void Print(Sqstack * S)
{
for(int i=0;i<=S->top;i++)
{
printf("%d ",S->data[i]);
}
printf("\n");
}
//出栈操作
Status Pop(Sqstack * S,SElemType * e)
{
if(S->top==-1) //栈底
{
return ERROR;
}
*e=S->data[S->top];
S->top--;
return OK;
}
//进栈操作
Status Push(Sqstack * S,SElemType e)
{
if(S->top==MAXSIZE-1) //栈满
{
return ERROR;
}
S->top++; //栈顶指针增加1
S->data[S->top]=e;
return OK;
}
/*栈模拟斐波那契数列*/
Status Fibonacci(Sqstack * S,int n)
{
int a[3];
a[0]=0;
a[1]=1;
int result,DeElem;
for(int i=0;i<(n/3);i++)
{
a[2]=a[0]+a[1];
Push(S,a[0]);
a[0]=a[1]+a[2];
Push(S,a[1]);
a[1]=a[2]+a[0];
Push(S,a[2]);
}
a[2]=a[0]+a[1];
Push(S,a[0]);
if((n%3==0))
{
Pop(S,&DeElem);
result=DeElem;
}
a[0]=a[1]+a[2];
Push(S,a[1]);
if((n%3==1))
{
Pop(S,&DeElem);
result=DeElem;
}
a[1]=a[2]+a[0];
Push(S,a[2]);
if((n%3==2))
{
Pop(S,&DeElem);
result=DeElem;
}
return result;
}
int main()
{
Sqstack S;
int n;
InitSqstack(&S);
printf("请输入n的值:\n");
scanf("%d",&n);
int result=Fibonacci(&S,n);
printf("结果为:%d\n",result);
return 0;
}
递归和循环的优缺点:
递归:空间和时间的消耗比较大代码简单
循环:代码复杂 速度较快
循环+栈可以实现递归操作
中缀后缀表达式之间的转换
给出中缀表达式 (6+4)*9-8/2
转成后缀 借助栈 6 4+9*82/-
规则为:
1、借助辅助栈
2、遇到数字或字符直接打印
3、遇到符号见符号与栈底元素进行优先级比较如果当前元素优先级高则直接入栈若当前元素优先级低则将栈内元素依次出栈直到当前元素优先级低为止再将栈内元素入栈
4、遇到左括号无条件入栈遇到右括号将栈内元素依次出栈直到左括号为止
由后缀转换成中缀:
借助辅助栈遇到数字或字符直接入栈遇到符号将栈底元素的下一个和栈底元素构成表达式