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
*/

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

#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;
}

 

时间: 2024-12-10 17:45:16

zstu4189——后缀表达式——逻辑运算的相关文章

前缀、中缀、后缀表达式以及简单计算器的实现

前缀表达式(波兰表达式).中缀表达式.后缀表达式(逆波兰表达式) 介绍 三种表达式都是四则运算的表达方式,用以四则运算表达式求值,即数学表达式的求解. 前缀表达式 前缀表达式是一种没有括号的算术表达式,与中缀表达式不同的是,其将运算符写在前面,操作数写在后面.为纪念其发明者波兰数学家Jan Lukasiewicz,前缀表达式也称为“波兰式”.例如,- 1 + 2 3,它等价于1-(2+3). 中缀表达式 中缀表达式就是一般的算数表达式,操作符以中缀形式出现在操作数之间. 后缀表达式 后缀表达式指

算法学习 - 表达树的建立(后缀表达式法),树的先序遍历,中序遍历,后序遍历

表达树就是根据后缀表达式来建立一个二叉树. 这个二叉树的每个叶子节点就是数,真祖先都是操作符. 通过栈来建立的,所以这里也会有很多栈的操作. 树的先序遍历,中序遍历,后序遍历的概念我就不讲了,不会的自行百度,不然也看不懂我的代码. 下面是代码: // // main.cpp // expressionTree // // Created by Alps on 14-7-29. // Copyright (c) 2014年 chen. All rights reserved. // #includ

四则运算使用栈和后缀表达式

我们在一般的四则运算都是中缀表达式. 别问我什么是中缀表达式. 我就知道符号两边是数字.也就是符号在中间. 1+3 什么是后缀表达式呢? 13+ 符号在后面. 那么就有人奇怪了,为什么我要使用后缀表达式呢? 问题就是运算的时候,在编程实现的时候,后缀表达式比中缀表达式好用呗. 没事,不理解那里好用没事,我们先把中缀表达式转换成后缀表达式然后实际看看就知道了. 从左到右依次读取 运算数,输出 左括号,入栈 右括号,将栈顶的运算符并输出,直到遇到左括号 运算符 { 若优先级大于栈顶运算符,入栈 若优

中缀表达式与前、后缀表达式转化简单的技巧[转]

35,15,+,80,70,-,*,20,/ //后缀表达方式 (((35+15)*(80-70))/20)=25 //中缀表达方式 /,*,+,35,15,-,80,70, 20 //前缀表达方式 人的思维方式很容易固定~~!正如习惯拉10进制.就对2,3,4,8,16等进制不知所措一样~~! 人们习惯的运算方式是中缀表达式.而碰到前缀,后缀方式..迷茫其实仅仅是一种表达式子的方式而已(不被你习惯的方式) 我这里教你一种也许你老师都没跟你讲的简单转换方式 一个中缀式到其他式子的转换方法 这里我

数据结构Java实现06----中缀表达式转换为后缀表达式

数据结构Java实现06----中缀表达式转换为后缀表达式 本文主要内容: 表达式的三种形式 中缀表达式与后缀表达式转换算法 一.表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3.我们从小做数学题时,一直使用的就是中缀表达式. 后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则),如:2 1 + 3 *.又比如3+(6-4/2)*5=23的后缀表达式为:3642/-5*+# (#符号为结束符

中缀表达式转为后缀表达式

** * 中缀表达式转后缀表达式 * * 作用:将一长串计算表达式转换为计算机易于操作的字符序列,用于计算器的设计 *  * 参与转换运算符 * +-/*()^% * * * 使用StringBuilder来保存转换出的后缀表达式 * 使用栈来操作运算符 * * * 转换原则 * 1.上述字符中()没有优先级值,+-优先级值为1,/*%优先级值为2,^优先级值为3 * 2.对于一个待计算的表达式,从左向右逐个检查每个字符 * 3.遇到数字,直接append到StringBuilder * 4.遇

中缀表达式转后缀表达式的方法:

1.遇到操作数:直接输出(添加到后缀表达式中)2.栈为空时,遇到运算符,直接入栈3.遇到左括号:将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出.5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈6.最终将栈中的元素依次出栈,输出.例如a+b*c+(d*e+f)*g ----> abc*+de*f+g*+ 遇到a:直接输出:后缀表达式:a堆栈:空 遇到+:堆栈:空,所以+入栈后缀表达式:a堆栈:+遇到b: 直

后缀表达式

我经常不厌其烦地向开发人员强调数据结构的重要性,也经常和团队分享一些常见算法.也许是大家写惯了业务代码,往往对数据结构的知识并不太在意.可不是嘛,只需要玩转QUID就能解决90%以上的问题,还费脑细胞学习基础知识干什么?当然,所有人都会回答"基础知识很重要,数据结构很重要".然而,当你发现工作几年的开发人员甚至不知道Array和List的区别时,也许会觉得他们当初是在说谎.这是真的,我发现大部分人不知道还有个链表叫"循环链表". 下面讲述的是多年前的故事. 表格曾是

中缀表达式转后缀表达式

写之前应该介绍一个厉害的波兰数学家--Jan Lukasiewicz(鲁卡谢维奇),他想到了一种不需要括号的后缀表达法,我们为了纪念他,把它称为逆波兰(Reverse Polish Notation,RPN)表示. 我们把平时所用的标准四则运算表达式,如:9+(3-1)×3+10/2,称为中缀表达式. 把9 3 1 - 3 * + 10 2 / +(此处由上一行的中缀表达式例子转化而来) 这种不需要括号表示的形式叫做后缀表达式,也是计算机非常喜欢的计算式. 转换规则: 从左到右遍历中缀表达式的每