实现场景规则的理想数据结构是什么?

时间:2014-01-10 23:35:30

标签: java algorithm data-structures

考虑以下场景,其中由ID定义的规则需要满足所有条件。

RULES

ID  Attribute1  Operator1  Value1   Attribute2  Operator2  Value1  ... And so on
-------------------------------------------------------------------
1    x            =          10         a         IN        5,10 
2    x            =          20         a         IN        10,15
3    x            =          20         a         IN        25,20

以上表示if(x=10) & if(a = 5 or a = 10} & ..., then ID = 1

如果格式为[x, a, ...]

的传入Feed
10, 5, ...
10, 10, ...
20, 20, ...

那么ID应该是

1
1
3

我希望检查是否有比以下解决方案更简单和更优雅的方式以及要使用的数据结构。

数据结构的缺点是什么?以下解决方案中使用的方法? (确定可能)

Assumptions:

  1. 属性列表暂时已修复,但可能会更改。
  2. 传入的Feed格式已修复。
  3. 不符合Java规则的实施。
  4. 接受算法答案,首选Java 7实现。
  5. 我的解决方案:

    1. 规则集的排列方式为Map<String, List<Criterion>>,其中key为ID,Criterion包含属性,运算符和值为字段。

    2. 数据组织为List<Map<String, String>>,其中key是属性(可以是x或a等),value是Feed中的实际值。

    3. 对于List<Map<String, String>中的每个条目,请执行以下操作以查找ID

    4. 循环遍历Map<String, List<Criterion>>中的每个条目并调用以下方法。如果返回true,我会记录ID,这是密钥并打破规则循环&amp;继续下一个数据项。

      public boolean executeRules(List<Criterion> list,
              Map<String, String> dataItem) {
          boolean fullMatch = true;
          if(CollectionUtils.isNotEmpty(list)){
              for(Criterion rule : list) {
                  switch (rule.getOperator()) {
                  case EQUAL_TO: //Similar to EQUAL TO
                      if(!rule.getValue().equals(dataItem.get(rule.getOperand()))){
                          fullMatch = false;
                      }
                      break;
                  case IN://Similar to IN
                      List<String> inCriteria = null;
                      if(rule.getValue() != null) {
                          inCriteria = Arrays.asList(((String) rule.getValue()).split("\\s*,\\s*"));
                          if(!inCriteria.contains(dataItem.get(rule.getOperand()))){
                              fullMatch = false;
                          }
                      } else {
                          fullMatch = false;
                      }
                      break;
      
      
                  default:
                      LOG.error("Invalid Operator: " + rule.getOperator());
                      fullMatch = false;
                      break;
                  }
                  if(!fullMatch) {
                      return false;
                  }
      
              }   
          } else {
              LOG.error("No Rules found");
              return false;
          }
      
          return true;
      }
      
    5. PS:不是作业;只是一些研究。

1 个答案:

答案 0 :(得分:3)

我认为您可以使用SmartParam库(http://smartparam.org/)。它专为此类评估而设计,非常通用,因此您甚至可以使用属性文件以及数据库