zstu4189——后缀表达式——逻辑运算

Description

 还记得大学里学过的模电么,今天就让我们将与或非变成一道题吧。

给你一个与或非的表达式,求出这个表达式的值,表达式总共有八种字符。

三种逻辑运算符按照优先级排列如下。

‘!’:表示取反。

‘&’:逻辑与。

‘|’:逻辑或。

两个字符‘T’,‘F‘分别表示true和 false。

另外还有左右括号,空格三种字符。跟一般的表达式一样,括号可以改变优先级。

 

Input

每组数据输入一行字符串,字符串长度小于等于100.

Output

 输出一个数0或1,表示逻辑表达式的答案。

Sample Input

T

Sample Output

1

HINT

 

Source

Wuyiqi

大意:代码能力要求很高

肉鸽的递归做法:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

 

char s[123];

int n;

 

int work0(int l, int r);

 

int find(int l){

    int cnt = 0;

    for(int i = l; i < n; i ++){

        if(s[i] == '(') cnt ++;

        else if(s[i] == ')') cnt --;

        if(cnt == -1) return i;

    }

}

 

int work(int l, int r){

    //printf("l = %d, r = %d\n", l, r);

    for(int i = l; i <= r; i ++){

        if(s[i] == '(') {

            int ri = find(i+1);

            int k = work0(i+1, ri-1);

           // printf("k = %d\n", k);

            return k;

        }

        if(s[i] == '!') {

            for(int j = i+1; j <= r; j ++){

                if(s[j] == ' ') continue;

                else if(s[j] == 'T') {

                    return 0;

                }else if(s[j] == 'F') {

                    return 1;

                } else if(s[j] == '('){

                    int ri = find(j+1);  return 1^work0(j+1, ri-1);

                }

            }

        }else if(s[i] == 'F') return 0;

        else if(s[i] == 'T') return 1;

    }

    return 0;

}

 

int work1(int l, int r){

    int cnt = 0;

    for(int i = l; i <= r; i ++){

        if(s[i] == '(' ) cnt ++;

        if(s[i] == ')') cnt --;

        if(s[i] == '&' && cnt == 0) return work1(l, i-1) & work1(i+1, r);

    }

    return work(l, r);

}

 

int work0(int l, int r){

    int cnt = 0;

    for(int i = l; i <= r; i ++){

        if(s[i] == '(' ) cnt ++;

        if(s[i] == ')') cnt --;

        if(s[i] == '|' && cnt == 0) {

            return work0(l, i-1) | work0(i+1, r);

        }

    }

    return work1(l, r);

}

 

int main(){

    while(gets(s) != NULL){

        n = strlen(s);

        printf("%d\n", work0(0, n-1));

    }

    return 0;

}

/*

!(T|F)|((T|F)&T)

F&T&F|T|T|F|!F

*/
View Code

铭神的模拟栈,后缀表达式做法:

#include<cstdio>

#include<cstring>

const int MX = 3110;

char s[MX];

struct Exp

{

   char op[MX];

   int num[MX];

   int top,tot;

   void inti()

   {

       top = 0;

       tot = 0;

       memset(op,0,sizeof(op));

       memset(num,0,sizeof(num));

       op[0] = '(';

   }

   int calc(char k,int a,int b)

   {

       if(k == '&'){

           return a && b;

       }

       else if( k == '|')

           return a || b;

   }

  bool prior(char a,char b)

  {

      if(b == '|')

          return a!='(';

      if(b == '&'){

          return a == '!' || a == '&';

      }

      return false;

  }

    void solve()

    {

        int len = strlen(s);

        s[len++] = '(';

        for(int i = 0 ; i < len;i++){

            if(s[i] == ' ')

                continue;

            else if(s[i] == '(')

                op[++top] = '(';

            else if(s[i] == ')'){

                if(top > 0 && op[top] != '('){

                    if(op[top] == '!'){

                        num[tot] = !num[tot];

                        top--;

                    }

                    else {

                        num[tot-1] = calc(op[top],num[tot-1],num[tot]);

                        tot--;

                        top--;

                    }

                }

                top--;

            }

            else if(s[i] == 'T' || s[i] == 'F')

                num[++tot] = s[i] == 'T' ? 1 : 0;

            else {

                while(top > 0 && prior(op[top],s[i])){

                        if(op[top] == '!'){

                        num[tot] = !num[tot];

                        top--;

                        }

                        else {

                        num[tot-1] = calc(op[top],num[tot-1],num[tot]);

                        tot--;

                        top--;

                     }

                   }

                        op[++top] = s[i];

                 }  

               }

                        printf("%d\n",num[1]);

                    } 

        };

        Exp E;

int main()

{

while(gets(s)!=NULL){

    E.inti();

    E.solve();

}

return 0;

}
View Code 

你可能感兴趣的:(表达式)