【问题标题】:Partition a predicate by "OR" logic in Java在 Java 中通过“OR”逻辑对谓词进行分区
【发布时间】:2017-05-16 22:22:23
【问题描述】:

如何根据OR (||)的逻辑将一个谓词划分为多个谓词?结果谓词的评估将与输入谓词相同。结果谓词不能包含逻辑OR (||)。 任何想法/算法/java/伪代码都会有所帮助。

示例输入输出:-

Input:  a>b || p>q
Output: a>b, p>q

Input: (a>b || p>q) && x>y
Output: (a>b && x>y), (p<q && x>y)

Input: (a>b || p>q) && (x>y || r>s)
Output: (a>b && x>y), (a>b && r>s), (p>q && x>y), (p>q && r>s)

Input: (a>b || p>q) && (x>y && r>s)
Output: (a>b && x>y && r>s), (p>q && x>y && r>s)

Input: (a>b || p>q) && (x>y && (r>s || m>n))
Output: (a>b && x>y && r>s),(a>b && x>y && m>n),(p>q && x>y && r>s),(p>q && x>y && m>n)

谢谢。

【问题讨论】:

  • 你想要遵循的模式是什么,是不是每个||&amp;&amp; 都在变化?因为我在您的示例中找不到共享模式
  • @Yahya 它只是将所有|| 推到顶层。在示例中替换 s/, / || /
  • 它减少了谓词中的 OR 逻辑。如果输入谓词的评估为真,则输出谓词的评估也为真。
  • 将输入字符串解析binary expression tree,然后为您拥有的每个|| 节点拆分该树。
  • 基本可以用变量替换每个不等式,替换||通过 + 和 && 通过 * 。现在所有正常的数学规则都是正确的,您想将方程转换为 (... * ... * ...) + (... * ... * ...) + ... 的形式,例如(a || b) && c ==> (a + b) * c = a * c + b * c ==> (a && c) || (b && c)。

标签: java algorithm tree logic


【解决方案1】:

您解析输入,例如(a&gt;b || p&gt;q) &amp;&amp; (x&gt;y &amp;&amp; (r&gt;s || m&gt;n)),转化为二叉表达式树。

           &&
    ||              &&
 >      >      >          ||
a b    p q    x y      >      >
                      r s    m n

然后找到|| 节点并克隆树两次,用节点的每一侧替换|| 节点。

       &&                              &&
 >           &&                   >           &&
a b     >          ||            p q     >          ||
       x y      >      >                x y      >      >
               r s    m n                       r s    m n

然后你再重复一遍,直到所有的|| 都被淘汰。

      &&                      &&                      &&                      &&
 >         &&            >         &&            >         &&            >         &&
a b     >      >        p q     >      >        a b     >      >        p q     >      >
       x y    r s              x y    r s              x y    m n              x y    m n

最后,打印结果。

a>b && (x>y && r>s)
p>q && (x>y && r>s)
a>b && (x>y && m>n)
p>q && (x>y && m>n)

【讨论】:

    【解决方案2】:

    这是一个 javascript 函数,它递归地解析输入然后乘以术语:

    function parsePredicateIntoBinaryTree(predicate) {
        function trimParen(a) {
            return a.trim().replace(/^\(*/, '').replace(/\)*$/, '').trim();
        }
        function multiplyTerms(s, t) {
            return s.reduce(function (c, a) {
                t.forEach(function (b) {
                    c.push(a.trim() + ' && ' + b.trim())
                });
                return c;
            }, []);
        }
        predicate = trimParen(predicate);
        var firstAmp = predicate.indexOf('&&')
        var leftTerm = predicate.substring(0, firstAmp);
        var rightTerm = predicate.substring(firstAmp + 2);
        var leftLeaf = leftTerm.indexOf('&&') < 0;
        var rightLeaf = rightTerm.indexOf('&&') < 0;
        if(leftLeaf && rightLeaf)
        {
            var a = trimParen(leftTerm).split('||');
            var b = trimParen(rightTerm).split('||');
            return multiplyTerms(a, b);
        }
        else if(leftLeaf && !rightLeaf)
        {
            var a = trimParen(leftTerm).split('||');
            var b = parsePredicateIntoBinaryTree(rightTerm);
            return multiplyTerms(a, b);
        }
        else if(!leftLeaf && rightLeaf)
        {
            var a = parsePredicateIntoBinaryTree(leftTerm);
            var b = trimParen(rightTerm).split('||');
            return multiplyTerms(a, b);
        }
        else if(!leftLeaf && !rightLeaf)
        {
            var a = parsePredicateIntoBinaryTree(leftTerm);
            var b = parsePredicateIntoBinaryTree(rightTerm);
            return multiplyTerms(a, b);
        }
    }
    function parsePredicate(predicate){
        console.log('Input:  ' + predicate);
        console.log('Output:  (' + parsePredicateIntoBinaryTree(predicate).join('),(') + ')');
    }
    
    parsePredicate('(a>b || p>q && (z<h || y>=e)) && (x>y && (r>s || m>n))');
    
    Input:  (a>b || p>q && (z<h || y>=e)) && (x>y && (r>s || m>n))
    Output:  (a>b && z<h && x>y && r>s),(a>b && z<h && x>y && m>n),(a>b && y>=e && x>y && r>s),(a>b && y>=e && x>y && m>n),(p>q && z<h && x>y && r>s),(p>q && z<h && x>y && m>n),(p>q && y>=e && x>y && r>s),(p>q && y>=e && x>y && m>n)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-22
      • 1970-01-01
      相关资源
      最近更新 更多