如果一系列布尔条件有效,则在运行时进行评估

时间:2015-10-01 14:01:49

标签: java

我有一个布尔条件列表,例如== 4< 5> 1等等。现在我想知道一系列和约束是否可行。让我们说< 5 > 1是可能的,< 5 > 9则不行。我曾想过把琴弦送进nashorn,但这让我无处可去。我怎样才能做到这一点?或者那里有没有图书馆在做这个工作?

编辑:我有3个运算符==,&lt; =和&gt; =并且不是整数的双倍(在现实生活中是的,较小或更高意味着较小/较高等于 - 但这不应该有所不同)。也许我可以扩大双打,即1022.30 - &gt; 10223

3 个答案:

答案 0 :(得分:1)

如果所有边界都是整数,则可以将每个条件转换为闭合范围。例如:

  • = x[x, x]
  • < x[Integer.MIN_VALUE, x - 1]
  • > x[x + 1, Integer.MAX_VALUE]

您可以为每个输入条件构建其中一个范围,然后通过计算下限的最大值和下限的最小值来获取范围的交集。

如果下限的最大值<=是上限的最小值,则可以满足条件。

整数示例:

boolean canBeSatisfied(Iterable<Pair<enum, Integer>> conditions) {
  int maxLower = Integer.MAX_VALUE;
  int minUpper = Integer.MIN_VALUE;
  for (Pair<enum, Integer> condition : conditions) {
    maxLower = Math.max(maxLower, getLowerBound(condition));
    minUpper = Math.min(minUpper, getUpperBound(condition));
  }
  return maxLower <= minUpper;
}

然后定义getLowerBoundgetUpperBound之类的内容:

int getLowerBound(Pair<enum, Integer> condition) {
  switch (condition.first) {
  case EQUALS:
  case GE:
    return condition.second;
  case GT:
    return condition.second + 1;
  case LT: case LE:
    return Integer.MIN_VALUE;
  }
}

int getUpperBound(Pair<enum, Integer> condition) {
  switch (condition.first) {
  case EQUALS:
  case GE: case GT:
    return Integer.MAX_VALUE;
  case LT:
    return condition.second - 1;
  case LE:
    return condition.second;
  }
}

您可以将相同的想法扩展到双重边界,但是您需要更加小心处理闭合边界和开放边界之间的差异。

如果你可以使用Guava,你可以使用Range类直接完成所有这些操作,使用工厂方法构建范围的适当实例,然后只取所有范围实例的交集。

答案 1 :(得分:0)

我会为运算符而不是interface使用enum。这将使您能够为所有运算符创建此接口的子类:

// File: Main.java
import java.util.ArrayList;
import java.util.List;

class Pair<L,R> {
    L left;
    R right;

    public Pair(L left, R right) {
        this.left = left;
        this.right = right;
    }
}

interface Operator {

    boolean calculate(double lhs, double rhs);
}

public class Main {

    private static Operator equals = new Operator() {

        @Override
        public boolean calculate(double lhs, double rhs) {
            return lhs == rhs;
        }

        @Override
        public String toString() {
            return "==";
        }
    };



    public static void main(String[] args) {

        Double x = 3.14;

        List<Pair<Operator, Double>> constraints = new ArrayList<>();
        constraints.add(new Pair(equals, 5.0));
        constraints.add(new Pair(equals, 3.14));

        for (Pair<Operator, Double> constraint : constraints) {

            Operator operator = constraint.left;
            double value = constraint.right;

            boolean result = operator.calculate(x, value);

            System.out.println(x + operator.toString() + value + "=" + result);
        }
    }
}

答案 2 :(得分:0)

我对您的设置了解不多,但假设只有三个运算符(><==),则只有三个主要案例需要处理:

  | > | < | ==
--+---+---+---
> |   | B | A 
--+---+---+---
< | B |   | C 
--+---+---+---
==| A | C |   

(抱歉丑陋的桌子)

首先,您需要检测案例,然后为每个案例定义方法,例如

possibleA(int biggerThan, int equalTo) {
    return equalTo > biggerThan;
}

,类似于案例B和C.