zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", 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
    ", 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
    ",num[1]);
                        } 
            };
            Exp E;
    int main()
    {
    while(gets(s)!=NULL){
        E.inti();
        E.solve();
    }
    return 0;
    }
    View Code 
  • 相关阅读:
    SQL整理5
    SQL整理1 数据类型
    SQL整理2
    JavaScript 的DOM操作
    JavaScript 数据类型
    JavaScript
    CSS样式表
    sqlserver数据库 提纲
    Python基础第十二天:二分法算法
    Python基础第十一天:递归函数
  • 原文地址:https://www.cnblogs.com/zero-begin/p/4442731.html
Copyright © 2011-2022 走看看