题目
描述
The objective of the program you are going to produce is to evaluate boolean expressions as the one shown next:
Expression: ( V | V ) & F & ( F | V )
where V is for True, and F is for False. The expressions may include the following operators: ! for not , & for and, | for or , the use of parenthesis for operations grouping is also allowed.
To perform the evaluation of an expression, it will be considered the priority of the operators, the not having the highest, and the or the lowest. The program must yield V or F , as the result for each expression in the input file.
本题的任务就是计算出题目所给的布尔表达式。其中V代表true,F代表false,! 代表not,& 代表 and(即大多数语言的&&),| 代表or(大多数语言的 ||)。输出就是V或者F。
输入
The expressions are of a variable length, although will never exceed 100 symbols. Symbols may be separated by any number of spaces or no spaces at all, therefore, the total length of an expression, as a number of characters, is unknown.
The number of expressions in the input file is variable and will never be greater than 20. Each expression is presented in a new line, as shown below.
每个表达式不会超过100个符号,但是每个符号之间会随机出现不同数量的空格(或者没有空格),所以表达式的长度和符号数量是未知的。
表达式本身的数量不会超过二十个,每个表达式都会是新的一行。
输出
For each test expression, print "Expression " followed by its sequence number, ": ", and the resulting value of the corresponding test expression. Separate the output for consecutive test expressions with a new line.
Use the same format as that shown in the sample output shown below.
每个表达式都要输出一行,具体格式可以参考样例。
样例输入
( V | V ) & F & ( F| V)
!V | V & V & !F & (F | V ) & (!F | F | !V & V)
(F&F|V|!V&!F&!(F|F&V))
样例输出
Expression 1: F
Expression 2: V
Expression 3: V
解题思路
布尔表达式的计算符包括两个中缀双目运算符和一个前缀单目运算符以及括号,而运算数则是V和F两种。因此本题可以说是简化版的运算。一个比较常规的思路是使用栈记录运算符和运算数进行计算。但对于本题来说,由于运算符和运算数都比较少,因此采用字符串扫描的方法再结合递归思想会是更为容易的方法。
本题所提供的布尔表达式可以分为两类:
- 表达式。这一类主要是包含双目运算符的表达式。
- 运算值。这一类主要是可以直接计算出结果的表达式。这里将括号也算作运算值。
它们的基本关系为:表达式 = 运算值 && 运算值(或者是||),而对于含括号的值则是运算值 = (表达式)。当然小的表达式(值)可以形成更大的表达式(值),最后整个输入内容就是最大的表达式(值)。这样递归思想就体现出来了。所以我们就可以逐位处理字符串,首先交给表达式函数处理,而表达式函数再根据情况调用运算值函数。
代码
代码中experssion代表处理表达式函数,factor代表处理值的函数。在两个函数中传位置的引用来代表当前字符串处理的位置。每“使用”一位字符就将位置往前推进一次。当然,由于我们采用的是扫描字符串的方式,在处理之前需要将输入的原始字符串做去空格处理,否则会出现各种各样奇怪的问题。