业务场景需要实现一个公式计算器,经过提炼成oj
题目如下:
给定一个只包括 ‘(’,’)’,’&’,’|’,‘1’,‘0’ 的字符串 s ,计算该表达式的布尔结果
注意:
其中 多重 ‘(’,’)’ 需要有计算优先级,先计算括号内部运算
‘&’ => 且
‘|’ => 或
‘1’ => true
‘0’ => false
示例 1:
输入:s = "1"
输出:true
示例 2:
输入:s = "((1&1|1&0|1)|(1&1))"
输出:true
示例 3:
输入:s = "((((1&0)|(1|0)&1)|1)|0)"
输出:true
示例 3:
输入:s = "1&1&1|1&0"
输出:false
示例 4:
输入:s = "((1&1|0|1)&(0&(0|1)))"
输出:false
解答思路:
public class MainClassC {
@Test
public void test(){
System.out.println(calculate("((1&1|1&0|1)|(1&1))"));
System.out.println(calculate("((((1&0)|(1|0)&1)|1)|0)"));
System.out.println(calculate("1&1&1|1&0"));
System.out.println(calculate("((1&1|0|1)&(0&(0|1)))"));
System.out.println(calculate("1"));
}
public static final Character LEFT_BRACKETS = '(';
public static final Character RIGHT_BRACKETS = ')';
public boolean calculate(String targetStr){
//逻辑表达式
StringBuilder expression = new StringBuilder();
//前值位逻辑
Boolean preBol = null;
//前值位逻辑是否存在开关
Boolean preFlag = false;
for (int i = 0; i < targetStr.length(); i++) {
char temp = targetStr.charAt(i);
//括号分割
if (temp == LEFT_BRACKETS){
//计算出当前左括号对应的右括号下标位置
int j = findClosing(targetStr.substring(i));
//递归到最小集进行计算逻辑表达式
preBol = calculate(targetStr.substring(i+1,i+j));
expression.append(TrueAndFalseEnum.code(preBol));
i += j;
preFlag = true;
}
//将当前数值追加至当前逻辑表达式中
if (preBol != null && preFlag){
preFlag = false;
continue;
}
expression.append(temp);
}
//计算逻辑表达式结果
return calcuteExpression(expression.toString());
}
/**
* 删除所有的括号对,并返回右括号的位置
* @param s
* @return
*/
private int findClosing(String s) {
int level = 0, i = 0;
for (i = 0; i < s.length(); i++) {
if (s.charAt(i) == LEFT_BRACKETS) level++;
else if (s.charAt(i) == RIGHT_BRACKETS) {
level--;
if (level == 0) break;
} else continue;
}
return i;
}
/**
* 计算逻辑表达式
* @param expression
* @return
*/
public boolean calcuteExpression(String expression){
if (expression.length() == 1){ //单个数值时
final char c = expression.charAt(0);
if (!SymbolConstant.symbolSet.contains(c)){
return TrueAndFalseEnum.value(c);
}
}
boolean retFlag = false;
char left = expression.charAt(0);
char right;
for (int i = 0; i < expression.length(); i++) {
final char temp = expression.charAt(i);
if (SymbolConstant.symbolSet.contains(temp)){
if (i+1<expression.length()){
//取出右值
right = expression.charAt(i+1);
//计算左右逻辑运算结果
//获取到计算处理类
final CalculateMethod calculateMethod = CalculateFactory.getCalculateMethod(temp);
if (calculateMethod == null){
System.out.println("获取对应的计算处理类未获取到,对应的符号为:"+temp);
}
//将计算结果重新赋值
left = TrueAndFalseEnum.code(calculateMethod.calculate(TrueAndFalseEnum.value(left), TrueAndFalseEnum.value(right)));
//跳一位
i++;
}else{
System.out.println("异常 下标越界异常");
}
}
}
retFlag = TrueAndFalseEnum.value(left);
return retFlag;
}
}
abstract class SymbolConstant{
public static final char AND_SYM = '&';
public static final char OR_SYM = '|';
public static Set<Character> symbolSet = new HashSet<>();
static {
symbolSet.add(AND_SYM);
symbolSet.add(OR_SYM);
}
}
@NoArgsConstructor
@AllArgsConstructor
@Data
class Brackets{
Character symbol; //括号
Integer strIndex; //括号在字符串中的下标位置
}
enum TrueAndFalseEnum{
TRUE('1',true),
FALSE('0',false);
private char code;
private boolean value;
TrueAndFalseEnum(char code, boolean value) {
this.code = code;
this.value = value;
}
public static Character code(boolean value){
for (TrueAndFalseEnum data : TrueAndFalseEnum.values()) {
if (data.getValue() == value){
return data.code;
}
}
return null;
}
public static Boolean value(char code){
for (TrueAndFalseEnum data : TrueAndFalseEnum.values()) {
if (data.getCode() == code){
return data.value;
}
}
return null;
}
public char getCode() {
return code;
}
public boolean getValue() {
return value;
}
public void setCode(char code) {
this.code = code;
}
public void setValue(boolean value) {
this.value = value;
}
}
class CalculateFactory{
public static CalculateMethod getCalculateMethod(char symbol){
switch (symbol){
case SymbolConstant.AND_SYM:
return new AndCalculateMethod();
case SymbolConstant.OR_SYM:
return new OrCalculateMethod();
}
return null;
}
}
interface CalculateMethod{
Boolean calculate(Boolean left,Boolean right);
}
class AndCalculateMethod implements CalculateMethod{
@Override
public Boolean calculate(Boolean left, Boolean right) {
return left && right;
}
}
class OrCalculateMethod implements CalculateMethod{
@Override
public Boolean calculate(Boolean left, Boolean right) {
return left || right;
}
}
版权声明:本文为Ru_yin_hai原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。