【问题标题】:java Split one list into multiple lists by exclusion of elementsjava通过排除元素将一个列表拆分为多个列表
【发布时间】:2020-09-23 02:16:52
【问题描述】:

有一个List,其中的元素根据一定的条件是互斥的

  1. 现在我需要根据这个互斥条件拆分成多个List

  2. 分区后互斥元素不能出现在子List中

  3. 切分后的子List个数要尽量减少

----------例如----------

  1. 原始列表[A, B, C]

  2. A与C互斥,A与B互斥,B与C互斥

  3. 可分为[A]、[B,C]或[C]、[A,B]

  4. 不要拆分成[A]、[B]、[C],因为拆分后子列表的总数不是最小的

谁能帮帮我?

【问题讨论】:

  • 你能提供一些例子吗?
  • 您描述中的语言似乎无处不在。使其一致。当您说拆分为多个列表时,您的意思是根据互斥条件对原始列表进行分区吗?此外,第 2 点谈到子列表。什么是子列表?你的意思是分区的子集。那么您是说分区的一个子集中的元素不能在同一分区的另一个子集中(互斥)?如果是这样,您本质上是在描述分区的定义
  • 互斥的条件是否总是产生布尔值?如果是这样,该条件将产生两个子集。或者这种情况会导致两个以上的值吗?
  • 请向我们展示您迄今为止尝试过的代码。
  • 例如1.原始列表[A,B,C] 2.A和C互斥,a和B互不互斥,B和C互不互斥 3.它可以分为[A],[B,C]或者[C],[A,B] 4.不要拆分成[A],[B],[C],因为拆分后子列表的总数不是最小值

标签: java algorithm collections


【解决方案1】:

据我了解,您希望根据集合中任意两个元素之间的任意比较来划分集合元素。我不认为 java 具有开箱即用的功能。您可以这样做的一种方法是:

public class Partition<T> {

    public List<Set<T>> partition(List<T> list, BiPredicate<T, T> partitionCondtion) {
        List<Set<T>> partition = new ArrayList<>();

        while (!list.isEmpty()) {
            // get first element from the remaining elements on the original list
            T firstElement = list.remove(0);

            // add first element into a subset
            // all elements on this subset must not be mutually exclusive with firstElement
            Set<T> subset = new HashSet<>();
            subset.add(firstElement);

            // get all remaining elements which can reside in the same subset of
            // firstElement
            List<T> notMutuallyExclusive = list.stream().filter(e -> !partitionCondtion.test(firstElement, e))
                    .collect(Collectors.toList());
            // add them to the subset of firstElement
            subset.addAll(notMutuallyExclusive);

            // add subset to partition (list of subsets)
            partition.add(subset);

            // remove elements added from original list
            list.removeAll(notMutuallyExclusive);
        }

        return partition;
    }

}

你可以像这样测试你的场景:

public class PartitionSmallTest {

    private BiPredicate<String, String> areMutuallyExclusive() {
        return (left, right) -> ("A".equals(left) && "C".equals(right)) || ("C".equals(left) && "A".equals(right));
    }

    @Test
    public void test() {
        List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));

        List<Set<String>> expected = new ArrayList<>();
        expected.add(Set.of("A", "B"));
        expected.add(Set.of("C"));

        List<Set<String>> actual = new Partition<String>().partition(list, areMutuallyExclusive());

        Assert.assertEquals(expected, actual);
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 2010-09-27
    • 2016-06-02
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多