备战省赛4 问题 F: Parentheses

判断表达式是否合法 以及是否正确;
合法 数学合法即可;
正确性 : 整个式子为 a 操作 b 型 a,b为整体 或 是被括号 形成的整体;
a+a proper;
(a)+((a+b)) improper;
a+(a+b)*c improper;
a+((a+b)*c) properl

题目描述

The correspondence among the operators and the operands can be clarified using parentheses. In a C program, for example, the expression a-b-c can be clarified as (a-b)-c since the minus operator is left associative.
The parentheses can be used to override the default precedences and associativities of operators. For instance, in the expression a-(b-c), the left associativity of the minus operator is overridden by the parentheses.
A novice C programmer Dennis has been stressed too much in remembering the operator precedences and associativities. Therefore, he made a new language namely ICPC (I can parenthesize C), in which the operator-operand correspondence should be clarified fully using parentheses; except for this, all the other features are same as C. For instance, one should write (a-b)-c instead of a-b-c and a+(bc) rather than a+bc.
However, the usage of the parentheses can be too much in some cases. For the expression a-b-c, it is enough to write
(a-b)-c
but one can write it as
(a-(b))-c
or as
((a-b)-c)
where the pairs of parentheses underlined are superfluous.
Dennis wants to convert the C expression into the ICPC expression, in which the pairs of parentheses should be used exactly as needed. You have to help Dennis. For simplicity, you can assume that the input C expression contains only five binary arithmetic operators (+, -, *, /, and %), left and right parentheses ( and ), and single-lowercase alphabet operands. Given such a C expression, write a program to determine whether it is an ICPC expression or not.
If the expression is not an error in ICPC, then it should not be an error in C. Once it is not an error in C, the usage of parentheses should be checked to determine whether it is a proper expression in ICPC or not. If the expression is not properly parenthesized, i.e., the number of parentheses is not exact as needed, then it is considered improper.
Beware that some of the input C expressions may be erroneous originally. For instance, a%/b is an error since it requires one more operand between % and / to be valid. As another example, a b + c is also an error since it requires one more operator between a and b.

输入

Your program is to read from standard input. The input consists of a single line containing a C expression. The expression is a string of single-lowercase alphabets, special symbols including left and right parentheses and five binary arithmetic operators (+, -, *, /, and %), and spaces. The input line contains at least one operand. The length of the input line (the number of characters in it) is no more than 1000 including the spaces and the single newline character at the end.

输出

Your program is to write to standard output. Print exactly one line. The line should contain one of the following words: error, proper, and improper. Print error if the input C expression is erroneous. Once it is not an error, print proper or improper depending on the parenthesized status of the expression: print proper if it is parenthesized properly with the exact number of parentheses needed for ICPC, and print improper otherwise.

样例输入
复制样例数据 a + a

样例输出
proper

代码如下 包含两种 work 的函数
一种使用栈 一种没用
好像不用栈会快一些;

#include<bits/stdc++.h>
using namespace std;
char a[112345];
int id[112345];
int n;
int ok()
{
    n=strlen(a);
    for(int i=0;i<n;i++)
    {
        if(isalpha(a[i]))
            id[i]=0;
        if(a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/'||a[i]=='%')
            id[i]=1;
        if(a[i]=='(')
            id[i]=2;
        if(a[i]==')')
            id[i]=3;
    }
    if(id[0]==3||id[0]==1||id[n-1]==2||id[n-1]==1)
        return 0;
    if(n==1&&id[0]==0)
        return 1;
    int x,y;
    for(int i=1;i<n;++i)
    {
        x=id[i-1];
        y=id[i];
        if(x==0)
        {
            if(y==2||y==0)
                return 0;
        }
        if(x==1)
        {
            if(y==1||y==3)
                return 0;
        }
        if(x==2)
        {
            if(y==1||y==3)
                return 0;
        }
        if(x==3)
        {
            if(y==0||y==2)
                return 0;
        }
    }
    int cnt=0;
    for(int i=0;i<n;i++)
    {
        if(id[i]==2)
            cnt++;
        else
        {
            if(id[i]==3)
            {
                if(cnt==0)
                    return 0;
                cnt--;
            }
        }
    }
    if(cnt==0)
        return 1;
    else
        return 0;
}
int work()
{
    int zhan[112345];
    memset(zhan,-1,sizeof(zhan));
    if(n==1)
        return 1;
    int cnt=0,ans=0;
    for(int i=0;i<n;i++)
        if(id[i]==1)
            ans++;
    int j=0;
    for(int i=0;i<n;i++)
    {
        if(id[i]==0)
            continue;
        if(id[i]<=2)
        {
            zhan[++j]=id[i];
        }
        if(id[i]==3)
        {
            int k;
            int flag=0;
            for(k=j;k>=1;k--)
            {
                if(zhan[k]==1)
                    flag++;
                if(zhan[k]==2)
                    break;
            }
            j=k-1;
            if(flag==1)
            {
                cnt++;
            }
            else
                return 0;
        }
    }
    if(ans==cnt+1)
        return 1;
    else
        return 0;
}

int work()
{
    int zhan[112345];
    memset(zhan,-1,sizeof(zhan));
    if(n==1)
        return 1;
    int cnt=0,ans=0;
    for(int i=0;i<n;i++)
        if(id[i]==1)
            ans++;
    stack<int>sta;
    int j=0;
    for(int i=0;i<n;i++)
    {
        if(id[i]==0)
            continue;
        if(id[i]<=2)
        {
            sta.push(id[i]);
        }
        if(id[i]==3)
        {
            int k;
            int flag=0;
            while(!sta.empty())
            {
                int Top=sta.top();
                sta.pop();
                if(Top==2)
                    break;
                else
                    flag++;
            }
            if(flag==1)
            {
                cnt++;
            }
            else
                return 0;
        }
    }
    if(ans==cnt+1)
        return 1;
    else
        return 0;
}
int main()
{
    gets(a);
    int l=strlen(a);
    int j=0;
    for(int i=0;i<l;i++)
    {
        if(a[i]!=' ')
        {
            a[j++]=a[i];
        }
    }
    a[j]=0;
    if( !ok() )
        printf("error\n");
    else
    {
        if( work() )
            printf("proper\n");
        else
            printf("improper\n");
    }
    return 0;
}

发布了18 篇原创文章 · 获赞 7 · 访问量 992

猜你喜欢

转载自blog.csdn.net/qq_43559193/article/details/89241810
今日推荐