需求的由来:
后台将过滤的功能放到客户端来做
给定一个逻辑表达式,客户端本地做逻辑判断,例如给定一个表达式:expr = a && (b || c)
需要解决的问题
- 如何判断一个逻辑表达式的真假
- 如何对一个逻辑表达式求值
判断逻辑表达式的真假
首先解决小括号的匹配问题,主要步骤分为如下几步:
- 初始化一个栈,在OC中可借助数组来实现栈这种数据结构
- 将给定的表达式字符串转化成C语言的字符数组
- 遍历转换后的C语言字符数组
- 遇到左括号"(",入栈
- 遇到右括号")",出栈一个元素,如果栈为空或者出栈元素不是与之匹配的左括号"(",则判断括号不匹配
- 如果匹配,则继续遍历字符数组,按照4、5规则直到遍历完成
如果遍历结束都能匹配,表示小括号能正确匹配
再进行逻辑表达式的判断,如果给定的表达式没有混杂小括号的话,可以通过OC中的谓词结合正则表达式来判断,主要代码如下:
+ (BOOL)validRegexExpression:(NSString *)express {
NSString *regex = @"^[0-9A-Za-z]+(([&]{2}|[|]{2})[0-9A-Za-z]+)*$";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
return [predicate evaluateWithObject:express];
}
引入小括号之后,可以结合上述2种方式:
- 首先判断小括号是否匹配,匹配成功之后对其括号中间的字符串判读是否满足是一个合法的逻辑表达式
- 如果满足则用一个临时字符进行代替,从而去掉小括号
- 如果不满足,则表示括号中间的不是一个合法的逻辑表达式,从而判断给定的整个字符串不是一个合法的逻辑表达式
对逻辑表达式求值
如果给定的一个逻辑表达式给真,那么可以对字符进行拆分的方式,例如给定的一个合法表达式是 a && (b || c),
- 初始化一个数组,遍历给定的字符串
- 将合法操作数、运算符 && 或者 || 作为一个字符串对象存储在数组中
- 对遇到的括号,对括号内的表达式进行逻辑判断,将判断结果的布尔值转成 NSNumber 存入数组中
- 按照上述方式,去除了所有的括号,并对括号内的逻辑表达式求值
- 如给出的逻辑表达式转化成 a && 0 或者 a && 1,即可从左到右对逻辑表达式求值