【发布时间】:2013-10-07 09:04:03
【问题描述】:
(ps。我只是重写了这个问题,因为我认为它处理的是排列,但它实际上是处理组合。)
更具体地考虑Map<String, List<WordGroupAndScore> baseMap,其中:
private static class WordGroupAndScore {
public final WordGroup wordGroup;
public final int score;
public WordGroupAndScore(final WordGroup wordGroup, final int score) {
this.wordGroup = wordGroup;
this.score = score;
}
}
baseMap.size() 是可变的,这意味着地图中可以有任意数量的Strings。同样对于baseMap 中的每个元素,baseMap.get(i).size() 是可变的。但baseMap 不能包含空列表。
现在我正在尝试找到所有可能的组合。代码本身用于检查发票中的数据,并非所有数据都在发票上可用,因此baseMap.size() 的数量可变。 baseMap 中每个元素的列表是可变的,因为找到的数据量取决于它是哪张发票。
(示例数据与示例中的数据不是一一对应的,实际上是WordGroupAndScore,但我将使用Strings 或BigDecimals 来表示示例中的数据)
baseMap(值和键对)严格(A 和List<B> 对)的示例数据:
("invoiceNumber", ["0001", "0002"])("invoiceDate", ["2013-10-07"])("priceExclVAT, [new BigDecimal("10.00")])("highVAT, [new BigDecimal("2.10")])("priceInclVAT, [new BigDecimal("12.10"), new BigDecimal("14.10")])
我想生成所有可能的数据组合。
示例输出,一个(“第一个”)组合(值和单个键对)严格(A 和 B 对):
("invoiceNumber", "0001")("invoiceDate", "2013-10-07"])("priceExclVAT, new BigDecimal("10.00"))("highVAT, new BigDecimal("2.10"))("priceInclVAT, new BigDecimal("12.10"))
示例输出,一个(“最后一个”)组合(值和单个键对)严格(A 和 B 对):
("invoiceNumber", "0002")("invoiceDate", "2013-10-07")("priceExclVAT, new BigDecimal("10.00"))("highVAT, new BigDecimal("2.10"))("priceInclVAT, new BigDecimal("14.10"))
所以不知何故,我需要遍历完整的 baseMap,记住/创建基于每个 baseMap.get(i).size() 的所有组合,但我几乎不知道从哪里开始。最大的问题是:我将如何记住这些组合,因为我的 baseMap 的大小是可变的。如果它不是可变的,那么我可以更轻松地完成它。
我希望问题足够清楚。
编辑:添加了我的一项尝试,但不起作用。
//Assumes that wordGroupsAndScores does not get changed during the process
private void processWordGroupAndScores(TemplateBean template) {
System.out.println();
System.out.println("--wordGroupsAndScores--");
for (Map.Entry<String, List<WordGroupAndScore>> entry : wordGroupsAndScores.entrySet()) {
System.out.println("Attribute = " + entry.getKey());
for (WordGroupAndScore wordGroupAndScore : entry.getValue()) {
System.out.println("WordGroupAndScore = " + wordGroupAndScore);
}
System.out.println(";");
}
System.out.println();
//create all possible unfinishedinvoices from wordgroupandscores
int[] indices = new int[wordGroupsAndScores.keySet().size()];
for (int index = 0; index < indices.length; index++) {
indices[index] = 0;
}
String[] keyLocation = new String[wordGroupsAndScores.keySet().size()];
int j = 0;
for (String key : wordGroupsAndScores.keySet()) {
keyLocation[j] = key;
j++;
}
processWordGroupAndScoresRecursive(indices, keyLocation, template);
}
private void processWordGroupAndScoresRecursive(int[] indices, String[] keyLocation, TemplateBean template) {
processWordGroupAndScoresWithIndices(indices, keyLocation, template);
boolean changedIndices = false;
for (int index = indices.length - 1; index >= 0; index--) {
if (indices[index] < wordGroupsAndScores.get(keyLocation[index]).size() - 1) {
indices[index]++;
changedIndices = true;
break;
}
}
if (changedIndices) {
processWordGroupAndScoresRecursive(indices, keyLocation, template);
}
}
private void processWordGroupAndScoresWithIndices(int[] indices, String[] keyLocation, TemplateBean template) {
System.out.println();
System.out.println("--Generated combination--");
UnfinishedInvoice unfinishedInvoice = new UnfinishedInvoice();
for (int index = 0; index < indices.length; index++) {
String key = keyLocation[index];
WordGroupAndScore wordGroupAndScore = wordGroupsAndScores.get(key).get(indices[index]);
System.out.println("Attribute = " + key);
System.out.println("WordGroupAndScore = " + wordGroupAndScore);
System.out.println(";");
setUnfinishedInvoiceAttribute(key, unfinishedInvoice, Utils.joinWordGroup(wordGroupAndScore.wordGroup, " "), wordGroupAndScore.score);
}
System.out.println();
unfinishedInvoice.verify();
if (templateMap.containsKey(template)) {
templateMap.get(template).add(unfinishedInvoice);
}
else {
List<UnfinishedInvoice> list = new ArrayList<>();
list.add(unfinishedInvoice);
templateMap.put(template, list);
}
}
让我们更清楚地看看它产生了什么,让我们只使用索引,而不是使用真实数据。
假设这是输入:[1, 1, 2, 1, 0]。它将地图表征为列表,其中元素是原始地图内列表中元素的索引。我们从地图中最后一个元素的组合开始。
使用我失败的代码作为输出:
[1, 1, 2, 1, 0][1, 1, 2, 0, 0][1, 1, 1, 0, 0][1, 1, 0, 0, 0][1, 0, 0, 0, 0][0, 0, 0, 0, 0]
这是不正确的,因为缺少很多值,例如缺少[0, 0, 0, 1, 0]。
这里出了什么问题?
【问题讨论】:
-
我认为您需要组合而不是排列。您想要给定 n 个列表的代码,它将通过从每个列表中获取一个元素来生成所有组合。这是你要问的问题吗?
-
@LefterisE 是的,那是正确的。
-
不只是一个简单的双循环(在地图上然后在列表上)解决您的问题吗?看起来就像示例中的那样。
-
@Dukeling 这并没有给出地图中所有列表元素的组合。
-
我没听明白,你想将每个地图元素与其列表中的每个元素结合起来,还是要将每个地图元素与地图中每个列表中的每个元素结合起来?
标签: java algorithm map combinations