题目链接:http://cxsjsxmooc.openjudge.cn/2018t2fallw3/1/
题目大意:
表达式:
您要生成的程序的目标是评估布尔表达式,如下所示:
(V | V)&F&(F | V)
其中V代表True,F代表False。表达式可能包括以!,&,|也允许使用括号进行操作分组。要执行表达式的评估,(不考虑&与|的优先级)程序必须产生V或F,作为输入文件中每个表达式的结果。输入表达式具有可变长度,但永远不会超过100个符号。符号可以由任意数量的空格分隔或根本不分隔空格,因此,表达式的总长度(如多个字符)是未知的。

思考:这题可以用递归实现,但是我们需要对布尔表达式有个明确的定义


由图可以看出表达式由一个或多个项组成(每个项前面可能有!)
项有两种组成形式,第一种形成递归,第二个是递归结束的条件。

对于每个表达式先处理!,然后调用计算项的函数
对于项,先判断是否有(,如果有就调用计算表达式的函数,没有就处理项的真值,并且retuen;

这样,就形成了项与表达式两个函数的相互递归。
注意:输入可能有空格,要处理一下,表达式前面的!可能有多个。处理到没有!为止

思考:之前都是做一个函数的递归(bfs, dfs),不知道递归还可以这么用,对递归的理解还不够,这题让我对递归有了新的认识,听说还可以用栈做,等会再想一想用栈做的思路。

介绍两个函数

char op=cin.peek(); //看一个字符,不取走
char op=cin.get();  //从输出流中取走一个字符
#include<bits/stdc++.h>
using namespace std;
#define LL long long

int xiang();
int bds();

int xiang()//计算表达式
{
    int result;
    char op;
    while(op=cin.peek(),op==' ')//处理空格
        cin.get();

    if(op=='!')//如果有!
    {
        int fh=1;
        while(cin.peek()=='!'||cin.peek()==' ')//处理可能的多个!
        {
            char pt=cin.get();
            if(pt=='!')
                fh=-fh;
        }
        result=bds();//计算项
        if(fh==-1)
            result=!result;


    }
    else
        result=bds();

    int more=1;
    while(more)//是否还有项
    {
        char p;
        while(p=cin.peek(),p==' ')//处理空格
        cin.get();

        if(p=='&'||p=='|')//如果还有项
        {
            p=cin.get();
            int value;

            char p1;
            while(p1=cin.peek(),p1==' ')
            cin.get();


            if(p1=='!')//重复计算项的工作
            {
                int fh=1;
                while(cin.peek()=='!'||cin.peek()==' ')
                {
                    char pt=cin.get();
                    if(pt=='!')
                        fh=-fh;
                }
                value=bds();
                if(fh==-1)
                    value=!value;
            }
            else
                value=bds();

            if(p=='&')//把两个项连接在一起
                result&=value;
            else
                result|=value;
        }
        else//如果没有项more=0跳出循环
            more=0;
    }
    return result;
}

int bds()//计算项
{
    int result;
    char op;
    while(op=cin.peek(),op==' ')//处理空格
        cin.get();

    if(op=='(')//如果有'('表示:项由(表达式)组成
    {
        cin.get();//处理括号(
        result=xiang();//计算项
        cin.get();//处理括号)
    }
    else//项由真值F或V组成
    {
        char p=cin.get();
        if(p=='V')
            result=1;
        else
            result=0;
    }
    return result;
}

int main()
{
    int i=1;
    while(cin.peek()!=EOF)//如果输入流还有字符
    {
        int k=xiang();
        char e=cin.peek();
        while(cin.peek()==' ')//处理每一行输入末尾的空格
        cin.get();

        printf("Expression %d: ",i++);
        if(k==0)
            cout<<"F"<<endl;
        else
            cout<<"V"<<endl;

        cin.get();//处理每一行输入完成的'\n'
    }

    return 0;
}