Java 布尔表达式到阈值表达式

Java 布尔表达式到阈值表达式,java,Java,我正在寻找一种可能的方法,将布尔表达式转换为阈值表达式 例如,我得到了一个booleanexpresion: ((A & B)|(C & D)) | ((A | B) & (C | D)) 它实际上意味着从以下集合中选择任意两个: {A,B,C,D} 如果我们使用阈值表达式,我们可以将其表示为: A,B,C,D 2outof4 但我找不到一个办法来让这一切顺利 有没有可能的办法 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我正在寻找一种可能的方法,将
布尔
表达式转换为
阈值
表达式

例如,我得到了一个
boolean
expresion:

((A & B)|(C & D)) | ((A | B) & (C | D))
它实际上意味着从以下集合中选择任意两个:

 {A,B,C,D}
如果我们使用阈值表达式,我们可以将其表示为:

A,B,C,D 2outof4
但我找不到一个办法来让这一切顺利

有没有可能的办法

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

实际上,我想知道的是:

给定如下布尔表达式:

((A & B)|(C & D)) | ((A | B) & (C | D))
是否可以识别表达式实际上是从集合{A,B,C,D}中选择2个元素

然后输出如下内容

A,B,C,D 2outof4

您可以使用
过滤器
对其进行过滤,然后对元素进行
计数

if (Stream.of(A, B, C, D).filter(x -> x).count() >= 2)

好的,总结一下,您需要确定布尔表达式是否是组合生成器

我相信下面列出的代码实现了这一点。您可以看到它包含一个结构与示例相同的表达式:

or(
    or(
        and(value("A"), value("B")),
        and(value("C"), value("D"))
    ), and(
        or(value("A"), value("B")),
        or(value("C"), value("D"))
    )
);
然后将其用作DSL以生成组合:

{A,B}
{A,C}
{A,D}
{B,C}
{B,D}
{C,D}
然后检查生成的组合是否满足以下条件:

  • 每一组必须有相同的长度-称之为r
  • 确定集合中包含的唯一值超集(如“A”、“B”等)的大小,称之为N
  • 集合的数量是否等于二项式(N,r)-从N中选择r值的方法的数量
  • 如果组合满足这些条件,则布尔表达式必须是从N中选择r值的生成器

    最后一行输出为:

    Optional[{A,B,C,D} 2 of 4]
    
    指示表达式是用于从4个值中选择2个值的生成器

    以下是完整的实施:

    import java.util.*;
    
    import static java.util.Collections.singleton;
    import static java.util.stream.Collectors.joining;
    import static java.util.stream.Collectors.toSet;
    
    class Combinations {
    
        static <T> Set<T> union(Collection<T> lhs, Collection<T> rhs) {
            final Set<T> result = new HashSet<>(lhs);
            result.addAll(rhs);
            return result;
        }
    
        static <T> String collToString(Collection<T> l) {
            return l.stream()
                .map(Object::toString)
                .collect(joining(",", "{", "}"));
        }
    
        static <T> Set<Set<T>> value(T value) {
            return singleton(singleton(value));
        }
    
        static <T> Set<Set<T>> or(Set<Set<T>> lhs, Set<Set<T>> rhs) {
            return union(lhs, rhs);
        }
    
        static <T> Set<Set<T>> and(Set<Set<T>> lhs, Set<Set<T>> rhs) {
            return lhs.stream()
                .flatMap(ls -> rhs.stream().map(rs -> union(ls, rs)))
                .collect(toSet());
        }
    
        static class Choose<T> {
            private static int binomial(final int n, final int r) {
                int ret = 1;
                for (int k = 0; k < r; k++) {
                    ret = ret * (n-k) /(k+1);
                }
                return ret;
            }
    
            static <T> Optional<Choose<T>> of(Set<Set<T>> sst) {
                final Set<Integer> sizes = sst.stream().map(Set::size).collect(toSet());
                if (sizes.size() != 1) {
                    return Optional.empty();
                } else {
                    final int r = sizes.iterator().next();
                    final Set<T> values = sst.stream().flatMap(Set::stream).collect(toSet());
                    final int n = values.size();
                    final int ncr = binomial(n, r);
                    if (sst.size() == ncr) {
                        return Optional.of(new Choose<>(values, r));
                    } else {
                        return Optional.empty();
                    }
                }
            }
    
            public final Set<T> values;
    
            public final int r;
    
            Choose(Set<T> values, int r) {
                this.values = values;
                this.r = r;
            }
    
            @Override
            public String toString() {
                return collToString(values) + " " + r + " of " + values.size();
            }
        }
    
        public static void main(String[] args) {
            // Generate the combinations.
            final Set<Set<String>> combos =
                or(
                    or(
                        and(value("A"), value("B")),
                        and(value("C"), value("D"))
                    ), and(
                        or(value("A"), value("B")),
                        or(value("C"), value("D"))
                    )
                );
    
            // Print the combinations to stdout.
            combos.stream()
                .map(ss -> collToString(ss))
                .forEach(System.out::println);
    
            Optional<Choose<String>> choose = Choose.of(combos);
            System.out.println(choose);
        }
    }
    
    import java.util.*;
    导入静态java.util.Collections.singleton;
    导入静态java.util.stream.Collectors.joining;
    导入静态java.util.stream.Collectors.toSet;
    类组合{
    静态集合并集(集合左、集合右){
    最终设置结果=新哈希集(lhs);
    结果:addAll(rhs);
    返回结果;
    }
    静态字符串collToString(集合l){
    返回l.stream()
    .map(对象::toString)
    收集(加入(“,”,“{,”,“}”);
    }
    静态设定值(T值){
    返回单例(单例(值));
    }
    静态设置或(左侧设置,右侧设置){
    返回接头(左、右);
    }
    静态设置和(左侧设置,右侧设置){
    返回lhs.stream()
    .flatMap(ls->rhs.stream().map(rs->union(ls,rs)))
    .收集(toSet());
    }
    静态类选择{
    私有静态整数二项式(最终整数n,最终整数r){
    int-ret=1;
    对于(int k=0;kcollToString(ss))
    .forEach(System.out::println);
    可选选择=choose.of(组合);
    System.out.println(选择);
    }
    }
    
    ?谷歌在这里帮不了什么忙:)请说得更具体些;例如,提供您正在寻找的结果的准确描述;然后:显示您为达到目标而编写的代码;并解释你被困在哪里。这不是一个免费的“我们为您实现您不明确的(!)要求”服务!我会使用
    Function.identity()
    而不是lambda-这没有多大区别,但我认为它更整洁。谢谢你的回复!但实际上我想要的是一个布尔表达式,比如:((a&B)|(C&D))|((a&B)&(C&D))我如何识别这个表达式的实际含义:从集合{a,B,C,D}中通过program@erick具体输出是什么?你说这是一个“阈值表达式”,但那是什么?类似于“(a,B,C,D)2of4”。实际上,我不知道如何描述这种表达式。所以我把它命名为“阈值表达式”。@erick我相应地扩展了答案。我发现一个问题是:如果我在整个表达式中再添加一个布尔值…例如:((a&B)(C&D))((a&B)和(C&D))(E&F)…它不能识别为((a,B,C,D)2of4);(E&F)……这是因为它无法过滤掉程序中的(E&F)。