当前位置: 首页 > 知识库问答 >
问题:

以所有可能的方式将列表拆分为两个子列表

姜聪
2023-03-14

例如,我有一个可变大小的列表

[1, 2, 3, 4]

我想用各种可能的方法把这个列表分成两部分:

([], [1, 2, 3, 4])
([1], [2, 3, 4])
([2], [1, 3, 4])
([3], [1, 2, 4])
([4], [1, 2, 3])
([1, 2], [3, 4])
([1, 3], [2, 4])
([1, 4], [2, 3])
([2, 3], [1, 4])
([2, 4], [1, 3])
([3, 4], [1, 2])
([1, 2, 3], [4])
([1, 2, 4], [3])
([1, 3, 4], [2])
([2, 3, 4], [1])
([1, 2, 3, 4], [])

我很确定这不是一个未知的问题,可能有一个算法,但是我找不到。此外,这不应使用任何外部库,而应使用简单的语言功能(循环、条件、方法/函数、变量等)在大多数语言中都可以找到。

我用Python写了一个hackish解决方案:

def get_all(objects):
    for i in range(1, len(objects)):
        for a in combinations(objects, i):
            for b in combinations([obj for obj in objects if obj not in up], len(objects) - i):
                yield State(up, down)
    if objects:
        yield State([], objects)
        yield State(objects, [])

但是,它使用了库功能,总体上不是很好看。

共有3个答案

汪弘光
2023-03-14

虽然在Python中,使用其广泛的库很容易得到结果,但在Java,您可以编写递归解决方案。以下内容将打印数组的所有可能组合:

public static void main(String[] args) {
    List<Integer> num = Arrays.asList(1, 2, 3, 4);
    List<List<Integer>> sublists = new ArrayList<List<Integer>>();
    for (int i = 0; i <= num.size(); i++) {
      permutation(num, sublists, i, new ArrayList<Integer>(), 0);
    }

    for (List<Integer> subList : sublists) {
        List<Integer> numCopy = new ArrayList<Integer>(num);
        numCopy.removeAll(subList);
        System.out.println("(" + subList + ", " + numCopy + ")");
    }
}

public static void permutation(List<Integer> nums, List<List<Integer>> subLists, int sublistSize, List<Integer> currentSubList,
      int startIndex) {
    if (sublistSize == 0) {
      subLists.add(currentSubList);
    } else {
      sublistSize--;
      for (int i = startIndex; i < nums.size(); i++) {
        List<Integer> newSubList = new ArrayList<Integer>(currentSubList);
        newSubList.add(nums.get(i));
        permutation(nums, subLists, sublistSize, newSubList, i + 1);
      }
    }
}

子列表包含迄今为止找到的所有组合。最后一个参数是当前子列表下一个元素的startIndex。这是为了避免重复。

袁旻
2023-03-14

一种更低级的解决方案,使用按位算术来计算子集,这应该很容易转换为Java:

def sublists(xs):
    l = len(xs)
    for i in range(1 << l):
        incl, excl = [], []
        for j in range(l):
            if i & (1 << j):
                incl.append(xs[j])
            else:
                excl.append(xs[j])
        yield (incl, excl)
晋俊贤
2023-03-14
l = [1, 2, 3, 4]
flags = [False] * len(l)
while True:
    a = [l[i] for i, flag in enumerate(flags) if flag]
    b = [l[i] for i, flag in enumerate(flags) if not flag]
    print a, b
    for i in xrange(len(l)):
        flags[i] = not flags[i]
        if flags[i]:
            break
    else:
        break

结果:

[] [1, 2, 3, 4]
[1] [2, 3, 4]
[2] [1, 3, 4]
[1, 2] [3, 4]
[3] [1, 2, 4]
[1, 3] [2, 4]
[2, 3] [1, 4]
[1, 2, 3] [4]
[4] [1, 2, 3]
[1, 4] [2, 3]
[2, 4] [1, 3]
[1, 2, 4] [3]
[3, 4] [1, 2]
[1, 3, 4] [2]
[2, 3, 4] [1]
[1, 2, 3, 4] []

它可以很容易地适应java:

public static void main(String[] args) {
    int[] l = new int[] { 1, 2, 3, 4 };
    boolean[] flags = new boolean[l.length];
    for (int i = 0; i != l.length;) {
        ArrayList<Integer> a = new ArrayList<>(), b = new ArrayList<>();
        for (int j = 0; j < l.length; j++)
            if (flags[j]) a.add(l[j]); else b.add(l[j]);
        System.out.println("" + a + ", " + b);
        for (i = 0; i < l.length && !(flags[i] = !flags[i]); i++);
    }
}
 类似资料:
  • 我想用Java中所有可能的方法将一个列表拆分为给定数量的n个子列表。 例如,其中n=3将包括以下列表(但不是一个完整的解决方案-完成将需要更多的空间): 等 我适应了另一个类似的问题的解决方案(以所有可能的方式将列表分割成两个子列表),但它只适用于创建2个子列表的列表,我正在努力掌握如何实现灵活而不是硬编码的子列表数量。 这是我的密码: 我需要创建n个数的EGroup对象添加到,而不是硬编码的2,

  • 使用:我必须更新存储在本地数据库中的当前订单。步骤如下: 从后端下载数据(~800项) 检查本地数据库是否已包含项。后端人员使用字符串作为主键。 如果该项不在数据库中,请添加它。 如果该项在数据库中,请更新它。 问题 你有一个如何用反应的方式解决这个问题的想法吗?有没有一个运算符,允许把可观察到的东西分成两个列表。或者我应该使用一个全局变量(似乎不是一个好主意)来保存信息,哪些数据要插入,哪些要更

  • 问题内容: 在Java中将列表拆分为两个子列表的最简单,最标准和/或最有效的方法是什么?可以更改原始列表,因此无需复制。方法签名可以是 [EDIT] 返回原始列表上的视图,如果修改了原始视图,该视图将无效。因此,除非它也放弃了原始参考文献,否则无法使用(或者,如Marc Novakowski的回答所述,使用但立即复制结果)。 问题答案: 快速半伪代码: 它使用标准的List实现方法,并避免了所有循

  • 问题内容: 我正在尝试找出将两个列表合并为所有可能组合的最佳方法。因此,如果我从两个这样的列表开始: 结果列表如下所示: 也就是说,它基本上会生成一个列表列表,其中包含所有可能的组合。 我一直在通过itertools进行工作,我肯定可以找到答案,但是我无法提出一种使其以这种方式起作用的方法。我最接近的是: 哪个产生了: 因此,它会执行每个列表中所有可能的项目组合,但不会执行所有可能的结果列表。我如

  • 问题内容: 我有这个清单(): 我想要这样的东西: 换句话说,我想使用值作为分隔符将列表拆分为子列表,以获得列表列表()。我正在寻找Java 8解决方案。我已经尝试过,但是我不确定这是我要找的东西。谢谢! 问题答案: 我目前想出的唯一解决方案是实现自己的自定义收集器。 在阅读解决方案之前,我想添加一些有关此的注释。我将这个问题更多地当作编程练习,我不确定是否可以使用并行流来完成。 因此,您必须意识

  • 感兴趣的是在同一pyspark数据帧中将列表的这一列拆分为多列的scala-spark实现 给定该数据帧: 我想要一个新的数据帧,它包含分解值并映射到我提供的列名称: 尝试: 但它的格式错误,我不知道如何映射到我的 colNames 列表: 在上面的链接中,python的解决方案是使用列表理解: 但它没有显示如何使用提供的列名列表,因为列名只是列的索引。