问题 F: 表达式括号匹配

问题 F: 表达式括号匹配


时间限制: 1 Sec  内存限制: 128 MB
[命题人:admin]

题目描述

假设一个表达式有英文字母(小写)、运算符(+,—,*,/)和左右小(圆)括号构成,以“@”作为表达式的结束符。请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返回“YES”;否则返回“NO”。表达式长度小于255,左圆括号少于20个。

输入

输入文件stack.in包括一行数据,即表达式,

输出

输出文件stack.out包括一行,即“YES” 或“NO”。

样例输入 Copy

2*(x+y)/(1-x)@

样例输出 Copy

YES
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map> 
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll; 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int maxn=1e5;
char a[maxn];
void inint(){
    scanf("%s",a);
}
int main(){
    inint();
    int len=strlen(a);
    int t=0;
    for(int i=0;i<len;i++){
        if(a[i]=='('){
            t++;
        }
        else if(a[i]==')'){
            t--;
        }
        if(t<0){
            printf("NO
");
            return 0;
        }
    }
    if(t==0){
        printf("YES
");
    }
    else{
        printf("NO
");
    }
    return 0;
}
 
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int maxn=1e5+10;
const int mod=1e9+7;
char str[1010];
char s[1010];
int cnt,val[1010];
stack<char>c;
stack<int>v;
int check(char a,char b) //计算优先级
{
    if(a=='('||b=='('){
        return 0;
    }  //如皋是左括号,只有遇到右括号的时候才计算这对括号内的表达式
    if(a=='+'||a=='-'){
        return 1; 
    } //加减是同级运算
    if(a=='*'&&(b=='*'||b=='/')){
        return 1;//乘除是同级运算
    }
    if(a=='/'&&(b=='*'||b=='/'))return 1;//乘除是同级运算
    return 0;// 不同级别的运算
}
int work(int x,int y,char a) //计算
{
    if(a=='+')return x+y;
    if(a=='-')return x-y;
    if(a=='*')return x*y;
    if(a=='/')return x/y;
}
int main()
{
    memset(s,0,sizeof(s));// s 和 val 数组,记录此时是数字还是运算符
    int n;
    cin>>n;
    scanf("%s",str);
    int l=strlen(str);
    str[l]=')'; // 开头结尾 加一对括号
    c.push('('); //先把开头的左括号入栈,方便后面计算优先级
    cnt=0;  //用一个cnt将数和运算符的前后关系区分开来
    int i=0;
    while(i<=l)
    {
        if(str[i]>='0'&&str[i]<='9') //处理这个数字
        {
            int x=0;
            while(str[i]>='0'&&str[i]<='9')
            {
                x=x*10+str[i]-'0';
                i++;
            }
            val[cnt++]=x; // 得到的 数字 存放在 val中
        }
        else  //运算符 或者是括号
        {
            if(str[i]==')') //遇到右括号就要找左括号,括号里面的运算级较高
            {
                while(!c.empty()&&c.top()!='(') //找到左括号,就停止
                {
                    s[cnt++]=c.top(); //把里面的运算符导出来,切记 此时存储的顺序和原式正好相反
                    c.pop();     //因为运用的是栈
                }
                c.pop();//把左括号给t出栈
            }
            else //运算符 或 左括号
            {
                while(!c.empty()&&check(str[i],c.top()))//这个时候就要看运算级别了,如果运算级别相同,则导出里面的符号
                {
                    //不同级别的运算先留下不处理
                    s[cnt++]=c.top();
                    c.pop();
                }
                c.push(str[i]);   //把这个符号加入栈中
            }
            i++;
        }
    }
    for(i=0; i<cnt; i++)  //总共有 cnt 个 数字 + 运算符
    {
        if(!s[i])  //如果是数字的话,先压入栈
            v.push(val[i]);
        else
        {
            int y=v.top();
            v.pop();
            int x=v.top();  //在栈中取出两个进行 + - * / 操作
            v.pop();
            v.push(work(x,y,s[i]));//得到的结果再压入栈中
        }
    }
    printf("%d
",v.top());
}
原文地址:https://www.cnblogs.com/lipu123/p/12337845.html