Java 如何在飞行中进行组合数学
我有一个非常奇怪的问题,有一些限制,使它很难解决。我有一个列表,我想把这些列表中的所有项目组合起来。每个项目都有一个名称和一个值。以下是一个例子: 主要清单:Java 如何在飞行中进行组合数学,java,algorithm,combinations,combinatorics,cartesian-product,Java,Algorithm,Combinations,Combinatorics,Cartesian Product,我有一个非常奇怪的问题,有一些限制,使它很难解决。我有一个列表,我想把这些列表中的所有项目组合起来。每个项目都有一个名称和一个值。以下是一个例子: 主要清单: 清单01: 项目01:名称:名称01,值:值01 项目02:名称:名称02,值:value02 清单02: 项目01:名称:名称03,值:值03 清单03: 项目01:名称:名称04,值:值04 项目02:名称:名称05,值:值05 最终结果应如下所示: 一些名单: 项目01:name01:value01,名称03:va
- 清单01:
- 项目01:名称:名称01,值:值01
- 项目02:名称:名称02,值:value02
- 清单02:
- 项目01:名称:名称03,值:值03
- 清单03:
- 项目01:名称:名称04,值:值04
- 项目02:名称:名称05,值:值05
- 项目01:name01:value01,名称03:value03,名称04:value04
- 项目02:名称02:value02,名称03:value03,名称04:value04
- 项目03:name03:value03,名称03:value03,名称04:value04
- 项目04:name01:value01,名称03:value03,名称04:value05
- 项目05:名称02:value02,名称03:value03,名称04:value05
- 项目06:名称03:value03,名称03:value03,名称04:value05
另外,我认为递归不会很好地工作。我一直在考虑使用while循环和一些嵌套循环,但是很难想象这应该如何工作。创建一个索引数组,每个列表一个索引,怎么样?可以通过依次对每个列表执行get()来读取当前组合。每个索引都将为零,然后前进到下一个有效的组合
index[0]++;
if (index[0] >= list[0].size()) {
index[0] = 0;
index[1]++;
if (index[1] >= list[1].size()) {
...
}
}
(将嵌套的if转换为迭代,作为读者的练习。)为什么不制作一个hashmap呢
Map<String,Map<String,String>> mainMap = new HashMap<String,Map<String,String>>();
for(List l : lists) {
for(Data d : l) {
String item = d.item;
String name = d.name;
String value = d.value;
Map<String,String> itemMap = mainMap.get(item);
if(item == null) {
itemMap = new HashMap<String,String>();
mainMap.put(item,itemMap);
}
itemMap.put(name,value);
}
}
Map mainMap=newhashmap();
对于(列表l:列表){
用于(数据d:l){
String item=d.item;
字符串名称=d.name;
字符串值=d.value;
Map itemMap=mainMap.get(项目);
如果(项==null){
itemMap=newhashmap();
mainMap.put(item,itemMap);
}
itemMap.put(名称、值);
}
}
稍后,您希望获得给定名称的所有值,而不管是哪一项
List<String> getValuesForName(String name) {
List<String> list = new LinkedList<String>();
for(Map<String,String map : mainMap) {
String value = map.get(name);
if(value != null) list.add(value);
}
return list;
}
列出getValuesForName(字符串名称){
列表=新建LinkedList();
对于(Map您不需要使用任何内存来解决此问题。可以从数学上获得列表的第n个元素,而无需创建整个组合。这是解释的,所以这是笛卡尔积,您要的是
假设有3个列表,包含2个、1个和3个元素。您将以2*1*3组合=6结束。(摘要:a*b*…*i)
现在从0到5取6个数字
void getCombiFor (int i, List <List <Integer>> li)
{
if (li.length > 0)
{
int idx = i % li.get (0).size ();
System.out.print (li.get (0).get(idx));
getCombiFor (i - idx, li.remove (0));
}
System.out.println ();
}
// pseudocodeline:
List li = List (List ('a', 'b'), List ('c'), List ('d', 'e', 'f'))
for (int i = 0; i < 6; ++i)
{
getCombiFor (i, li);
}
每个索引都从0开始,obvs。您的示例不太清楚,并且包含一个错误。我可以推荐3个包含2、1和3个元素的列表((a、b)(c)(d、e、f))。这将导致6个解决方案(笛卡尔积或叉积)。阅读a:=(name01,value01)如果你愿意的话。但是你的例子在某个列表项03:n3v3-n3v3-中有两次。这不是故意的,是吗?
Lists = ((a,b), (c), (d,e,f))
acd
bcd
acf
bcf
ace
bce