我正在开发一个应用程序,其中我有许多块应该放在一行上。即有不同数量的块,每个块都有不同的长度,应该放在线上。块之间至少需要一个空元素。
我希望有效地获得线路上所有可能的排列。
例如,我有一条长度为15的线,并希望放置1个,6个和1个大小的块。
顺序很重要,即在我的例子中,1大小的块总是应该是6大小块的左右。
可能的排列是
X.XXXXXX.X.....
X..XXXXXX.X....
...
.....X.XXXXXX.X
如何以更高级别的语言有效地生成所有可能的排列,例如爪哇?
答案 0 :(得分:3)
这样做的一种方法是递归接近它:
将这种递归逻辑转换为实际的Java应该不会太困难。下面的代码是为了便于阅读而设计的,可以稍微优化一下:
public List<String> allBlockOrderings(int rowLength, List<Integer> blockSizes) {
/* Case 1: Not enough space left. */
if (spaceNeededFor(blockSizes) > rowLength)) return Collections.EMPTY_LIST;
List<String> result = new ArrayList<String>();
/* Case 2: Nothing to place. */
if (blockSizes.isEmpty()) {
result.add(stringOf('.', rowLength));
} else {
/* Case 3a: place the very first block at the beginning of the row. */
List<String> placeFirst = allBlockOrderings(rowLength - blockSizes.get(0) - 1,
blockSizes.subList(1, blockSizes.length()));
for (String rest: placeFirst) {
result.add(stringOf('X', blockSizes.get(0)) + rest);
}
/* Case 3b: leave the very first spot open. */
List<String> skipFirst = allBlockOrderings(rowLength - 1, blockSizes);
for (String rest: skipFirst) {
result.add('.' + rest);
}
}
return result;
}
您需要实现spaceNeededFor
方法,该方法返回可能包含给定列块列表的最短行的长度,以及stringOf
方法,该方法接收字符和一个数字,然后返回给定字符的那么多副本的字符串。
希望这有帮助!
答案 1 :(得分:1)
对我而言,以另一种方式思考问题似乎更容易:
我们按固定顺序固定了块,用点分隔。我们可以通过在允许的位置上分配剩余的点来创建所有排列。
该行的固定部分的长度为:
fixed_len = length_of_all_blocks + number_of_blocks - 1
剩余点数
free_dots = length_of_line - fixed_len.
未结头寸的数量是
pos_count = number_of_blocks + 1
现在我们必须找到如何将free_dots放入pos_count的所有排列。
答案 2 :(得分:0)
很难确定什么是“有效实现”,因为输出可能非常大,因此即使快速实现也不够快。
我会使用动态编程和递归技术来完成这项任务。递归的fuoction应该有两个参数 - 未使用的数字列表和行的剩余长度。在里面它将是一个简单的循环。您应该存储您已经知道的结果。我相信你可以自己处理细节。编辑:我们的朋友已经为你完成了这件事: - )。
顺便说一下,这样的任务的目标是什么?它让我重新关注网格中的图片,其中每行和每列都有这样的数字,你需要解码图片。有更好的方法来解决这个问题。