例如,我有一个可变大小的列表
[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, [])
但是,它使用了库功能,总体上看起来不是很好。
最佳答案
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 - 以所有可能的方式将列表拆分为两个子列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29656649/