给定n个用户(u_1,u_2,...,u_n)和k个组(g_1,g_2,...,g_k),创建所有组的所有可能组合。基本上,最后,每个组合都是Map< Integer,Integer>,其中第一个Integer是用户ID,第二个Integer是组ID。例如,[(u_1,g_1),(u_2,g_1).. ..,(u_n,g_1)]是一种可能的组合。
将有k ^ n种组合。
我搜索并看到了类似的问题,但他们确实有一些额外的条件不适用于我的问题。就我而言,每组都没有限制,没有均匀或均匀分布。
您能否建议使用Java快速完成此操作?
由于
到目前为止我的尝试: 我尝试为每个用户创建一个for循环,但我面临的问题是我无法定义for循环的数量。
所以我切换到递归,但坚持为内部调用函数创建参数。尽管如此仍在努力。
请注意,这不是“n选择k”。 “n选择k”是指所有用户都相同,但这里的用户显然不相同。
行。我为此创建了一个解决方案。基本上,这是一个动态编程问题。假设您已为j个用户和k个位置创建了一个地图列表(组合)。要为j + 1个用户和k个位置创建,需要2个循环:对于每个Map,对于每个i = 1到k,Map.put(user_j + 1,k))。是递归和迭代。递归,因为您需要将旧映射传递给新迭代。就是这样。
答案 0 :(得分:4)
这类问题的传统解决方案是使用递归:如果有n = 0个用户,则唯一可能的分组是空组。否则,取出第一个用户并为其他n-1个用户生成解决方案。使用子问题的解决方案,通过将第一个用户分配给k个可能的组中的每一个来生成最终解决方案。
在代码中:
import java.util.*;
class Grouping {
public static void main(String[] args) {
List<?> groups = grouping(Arrays.asList(1,2,3), Arrays.asList(4,5,6,7));
System.out.println(groups.size());
System.out.println(groups);
}
static List<Map<Integer,Integer>> grouping(List<Integer> users, List<Integer> groups) {
if (users.isEmpty()) {
Map<Integer,Integer> empty = Collections.emptyMap();
return Collections.singletonList(empty);
} else {
Integer user = users.get(0);
List<Map<Integer,Integer>> subs = grouping(users.subList(1,users.size()), groups);
List<Map<Integer,Integer>> solutions = new ArrayList<>();
for (Integer group: groups) {
for (Map<Integer,Integer> sub : subs) {
Map<Integer,Integer> m = new HashMap<>(sub);
m.put(user, group);
solutions.add(m);
}
}
return solutions;
}
}
}
答案 1 :(得分:2)
好的,这是一个简单的想法 让我们首先假设每个user_id在{0,... n-1},并且group_id在{0,... k-1},我们可以稍后将这些数字映射回实际ID。 / p>
现在,您基本上想要做的是通过 Base k 数字系统中的所有n位数字进行迭代,即每个数字0 <= base&lt; ķ。
所以,你从数字开始是0000 ... 00(n-neroes),你以kkkk .... kk(n个名义 k )结束。对于每个这样的数字,位置表示user_id,数字值是该用户的group_id。
因此,您需要实现的主要工具是表示此n位数序列的类Combination
(尝试ArrayList
或简单int[] array
),并执行increment()
操作正确(我认为递归是执行此实现的最佳方式)。可能您也可以使用方法isMaxReached()
来检查所有数字是否都有值k
。
然后你会有一个循环:
组合组合=新组合(); //用n -zeroes初始化
while (!combination.isMaxReached()) {
combination.increment();
}
如果您需要更多有关实施的详细信息,请与我们联系。
希望有所帮助。
答案 2 :(得分:0)
看起来我们有以下内容:
n
不同的数字(用户)k
设置(群组)目标是:
1..n
如果这是你想要的,那么我会以递归的方式攻击它:
示例:
n = 3, k = 2
n = 2, k = 2
n = 1, k = 2
n = 0, k= 2
result: [({},{})]
result: [({1},{}), ({},{1})]
result: [({1,2},{}), ({2},{1}), // j=1, union 1st with {2}
({1},{2}), ({},{1,2})] // j=2, union 2nd with {2}
result: [
({1,2,3},{}), ({2,3},{1}), ({1,3},{2}), ({3},{1,2}), // j=1, union 1st with {3}
({1,2},{3}), ({2},{1,3}), ({1},{2,3}), ({},{1,2,3}) // j=2, union 2nd with {3}
]
答案 3 :(得分:-1)
所以你想要像k1,n1,k1,nN ... kN,nN等地图。
- 您需要2个循环
- 首先循环播放群组。在每个组中,循环遍历所有用户......并在第二个循环中,将(组,用户)放入散列映射...
- 使用上述算法的代码。
醇>