Algorithm 有效地计算一组给定的;积木;排成一行
我正在开发一个应用程序,其中我有许多块应该放在一条线上。也就是说,有不同数量的块,每个块的长度不同,应放置在线路上。块之间需要至少有一个空元素 我想有效地得到所有可能的块排列 例如,我有一条长度为15的线,希望放置大小为1、6和1的块 顺序问题,即在我的示例中,1尺寸块始终应位于6尺寸块的左侧和右侧 可能的排列是Algorithm 有效地计算一组给定的;积木;排成一行,algorithm,language-agnostic,permutation,Algorithm,Language Agnostic,Permutation,我正在开发一个应用程序,其中我有许多块应该放在一条线上。也就是说,有不同数量的块,每个块的长度不同,应放置在线路上。块之间需要至少有一个空元素 我想有效地得到所有可能的块排列 例如,我有一条长度为15的线,希望放置大小为1、6和1的块 顺序问题,即在我的示例中,1尺寸块始终应位于6尺寸块的左侧和右侧 可能的排列是 X.XXXXXX.X..... X..XXXXXX.X.... ... .....X.XXXXXX.X 如何以更高级别的语言(如Java)高效地生成所有可能的排列?一种方法是递归地处
X.XXXXXX.X.....
X..XXXXXX.X....
...
.....X.XXXXXX.X
如何以更高级别的语言(如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;
}
public列出所有blockordering(int行长度,列出块大小){
/*案例1:没有足够的空间*/
if(spaceneedfor(blocksize)>rowLength))返回Collections.EMPTY_列表;
列表结果=新建ArrayList();
/*案例2:没什么可放的*/
if(blockSizes.isEmpty()){
结果.添加(stringOf('.',rowLength));
}否则{
/*案例3a:将第一个块放在行的开头*/
List placeFirst=allBlockOrderings(行长度-blockSizes.get(0)-1,
blockSizes.subList(1,blockSizes.length());
for(字符串剩余:placeFirst){
结果.add(stringOf('X',blocksize.get(0))+rest);
}
/*案例3b:让第一个位置保持打开状态*/
List skipFirst=所有区块排序(行长-1,区块大小);
用于(字符串休息:skipFirst){
结果.添加('.'+rest);
}
}
返回结果;
}
您需要实现spaceneedFor
方法,该方法返回可能包含给定块列表的最短行的长度,以及stringOf
方法,该方法接收一个字符和一个数字,然后返回给定字符的多个副本的字符串
希望这有帮助 一种方法是递归地接近它:
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;
}
public列出所有blockordering(int行长度,列出块大小){
/*案例1:没有足够的空间*/
if(spaceneedfor(blocksize)>rowLength))返回Collections.EMPTY_列表;
列表结果=新建ArrayList();
/*案例2:没什么可放的*/
if(blockSizes.isEmpty()){
结果.添加(stringOf('.',rowLength));
}否则{
/*案例3a:将第一个块放在行的开头*/
List placeFirst=allBlockOrderings(行长度-blockSizes.get(0)-1,
blockSizes.subList(1,blockSizes.length());
for(字符串剩余:placeFirst){
结果.add(stringOf('X',blocksize.get(0))+rest);
}
/*案例3b:让第一个位置保持打开状态*/
List skipFirst=所有区块排序(行长-1,区块大小);
用于(字符串休息:skipFirst){
结果.添加('.'+rest);
}
}
返回结果;
}
您需要实现spaceneedFor
方法,该方法返回可能包含给定块列表的最短行的长度,以及stringOf
方法,该方法接收一个字符和一个数字,然后返回给定字符的多个副本的字符串
希望这有帮助 很难确定什么是“高效实现”,因为输出可能非常大,因此即使是快速实现也不够快 我会使用动态规划和递归技术来完成这样的任务。递归函数应该有两个参数——未使用的数字列表和行的剩余长度。里面将是一个简单的循环。您应该存储您已经知道的结果。我相信你可以自己处理细节。编辑:我们的朋友已经为y做过了
free_dots = length_of_line - fixed_len.
pos_count = number_of_blocks + 1