0
点赞
收藏
分享

微信扫一扫

栈的数组实现与相关算法题

IT程序员 2022-05-06 阅读 66
算法

实现方式:数组+栈顶指针

Int sta[maxn]

Int top

操作:

Void push(x):入栈

Top++;

sta[top]=x;

void pop(x):出栈

top--;

int top():查询栈顶元素

return sta[top]

int empty():

if(top==0)return 1;

return 0;

int size():

return top+1;

栈的应用:

  1. 括号匹配 

例题:洛谷P1739 

因为只涉及到计数所以构建一个虚拟栈,输入字符c,如果输入字符为”(“,则入栈,top++,若输入字符为”)”,若栈不为空,则弹出栈顶元素与右括号匹配,top--,若栈为空,则输出”NO”,结束程序,输入字符为”@”,结束输入,检查栈是否为空,若为空则匹配完全,不为空则有剩余左括号未匹配,输出“NO”.

//程序说明:栈的数组实现 
#include<bits/stdc++.h>
using namespace std;
//int sta[256];
char c;
int top;//栈顶指针虚拟栈 
int main()
{
	while(cin>>c){
		if(c=='@')break;
		if(c=='(')top++;
		if(c==')'&&top>0)top--;
		else if(c==')'&&top==0){
			cout<<"NO";
			return 0;
		}
	} 
	if(top==0)cout<<"YES";
	else cout<<"NO";
	return 0;
}

  1. 表达式求值
  1. 后缀表达式,不用考虑优先级,只需构建一个数据栈,实现较为简单 

 例题:洛谷(P1449)

 

#include<bits/stdc++.h>
using namespace std;
char c;
int sta[1001];
int top=-1;
int num,t; 
int main()
{
    while(cin>>c){
        if(c=='@')break;
        if(c=='.'){
            top++;
            sta[top]=num;
            num=0;
        }
        else if(c>='0'&&c<='9')num=num*10+c-'0';
        else{
            switch(c){
                case '-':
                    t=sta[top-1]-sta[top];
                    top--;
                    sta[top]=t;
                    break;
                case '+':
                    t=sta[top]+sta[top-1];
                    top--;
                    sta[top]=t;
                    break;
                case '*':
                    t=sta[top]*sta[top-1];
                    top--;
                    sta[top]=t;
                    break;
                case '/':
                    t=sta[top-1]/sta[top];
                    top--;
                    sta[top]=t;
                    break;
            }
                
        }
    }
    cout<<sta[top];
    return 0;
} 

 

     2. 中缀表达式求值

构建两个栈,一个栈装载数字,一个栈装载运算符,如何处理运算符优先级?在运算符入栈过程中,如果当前运算符优先级低于栈顶优先级,则栈顶优先级出栈运算后当前运算符入栈,左括号则直接入栈,遇到右括号则while向下扫描,抛出括号内运算符并计算,直到遇到左括号。最后,两个栈中剩余元素可直接匹配运算,运算结束,输出数字栈栈顶元素。

例题:(洛谷 P1981)

#include<bits/stdc++.h>
using namespace std;
int sta1[100001];
int top1=-1,top2=-1,num,ans;
int sta2[100001];
int main()
{
	string s;
	cin>>s;
	for(int i=0;i<s.length();i++){
		//数字part 
		if(i==s.length()-1&&s[i]>='0'&&s[i]<='9'){
			ans=ans*10+s[i]-'0';
			top1++;
			sta1[top1]=ans%100000;
		}
		if(s[i]>='0'&&s[i]<='9'){ 			
			ans=ans*10+s[i]-'0'; 
		}
		//字符part 
		else{
		    //第一步结算数字入栈 
		    top1++;
			sta1[top1]=ans%100000;
			ans=0;
			//第二步处理字符 
			if(s[i]=='('){//左括号直接入 
				top2++;
				sta2[top2]=0;
				continue;
			}
			else if(s[i]==')'){//右括号,清算括号内容 
				while(sta2[top2]!=0){//直到遇到左括号
				    switch(sta2[top2]){//运算 
				    case 1:
				    	num=sta1[top1-1]+sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
				    case 2:
					    num=sta1[top1-1]-sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
				    case 3:
				    	num=sta1[top1-1]*sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
				    case 4:
				    	num=sta1[top1-1]/sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
			        }
				}
			    top2--;//清除左括号 
			    continue;
			}
			//非括号字符 
			int sym;//为运算符确定标志数 
			switch(s[i]){
				case '+':sym=1;break;
				case '-':sym=2;break;
				case '*':sym=3;break;
				case '/':sym=4;break;
			}
			if((sym==1||sym==2)&&(sta2[top2]==3||sta2[top2]==4)){//优先级低要先抛出栈顶的运算符 
				switch(sta2[top2]){//计算 
				    case 1:
				    	num=sta1[top1-1]+sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
				    case 2:
					    num=sta1[top1-1]-sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
				    case 3:
				    	num=sta1[top1-1]*sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
				    case 4:
				    	num=sta1[top1-1]/sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
			    }
			    sta2[top2]=sym;//字符入栈 
			}		
			else{//优先级更高,压住 
				top2++;
				sta2[top2]=sym;
			}	
		}
	}
	//结算 
	while(top2>=0){
		switch(sta2[top2]){
				    case 1:
				    	num=sta1[top1-1]+sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
				    case 2:
					    num=sta1[top1-1]-sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
				    case 3:
				    	num=sta1[top1-1]*sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
				    case 4:
				    	num=sta1[top1-1]/sta1[top1];
				    	top1--;
				    	sta1[top1]=num%100000;
					    break;
		}
		top2--;
	}
	cout<<sta1[top1]%10000;//输出最终结果 
	return 0;
}

举报

相关推荐

0 条评论