【发布时间】:2015-11-29 13:45:59
【问题描述】:
我有一个数组,其中包含 3 个文件中的总行数。示例:[3,4,5]。我想生成一个数字序列,以有条不紊的方式将该数组计数为零,从而为我提供三个文件中的每个行组合。此示例使用 3 个文件/长度为 3 的数组,但该算法应该能够处理任意长度的数组。
对于上面的示例,解决方案如下所示:
[3,4,5] (line 3 from file 1, line 4 from file 2, line 5 from file 3)
[3,4,4]
[3,4,3]
[3,4,2]
[3,4,1]
[3,4,0]
[3,3,5]
[3,3,4]
[3,3,3]
[3,3,2]
等等……
我第一次尝试为此递归地递减数组中的一个位置,当该位置达到零时 - 递减它之前的位置。但是,我无法继续递减比最后两个位置更远的位置。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FilePositionGenerator {
public static void main(String[] args) {
int[] starterArray = {2, 2, 2};
int[] counters = starterArray.clone();
List<Integer> results = new ArrayList<Integer>();
FilePositionGenerator f = new FilePositionGenerator();
f.generateFilePositions(starterArray, counters, (starterArray.length - 1), results);
}//end main
void generateFilePositions(int[] originalArray, int[] modifiedArray, int counterPosition, List<Integer> results) {
if (modifiedArray[counterPosition] == 0 && counterPosition > 0) {
modifiedArray[counterPosition] = originalArray[counterPosition];
counterPosition = counterPosition - 1;
} else {
modifiedArray[counterPosition] = modifiedArray[counterPosition] - 1;
System.out.println(Arrays.toString(modifiedArray));
generateFilePositions(originalArray, modifiedArray, counterPosition, results);
}
}
}
我知道要处理可变长度数组,算法必须是递归的,但我很难考虑清楚。所以我决定尝试不同的方法。
我第二次尝试生成算法时使用了双指针方法,该方法将指针保持在当前倒计时位置[最右边的位置],以及指向下一个非最右边位置(pivotPointer)的指针,该指针在最右边时将递减位置达到零。像这样:
import java.util.Arrays;
class DualPointer {
public static void main(String[] args) {
int[] counters = {2, 2, 2}; // initialize the problem set
int[] original = {2, 2, 2}; // clone a copy to reset the problem array
int[] stopConditionArray = {0, 0, 0}; // initialize an object to show what the stopCondition should be
int pivotLocation = counters.length - 1; // pointer that starts at the right, and moves left
int counterLocation = counters.length - 1; // pointer that always points to the rightmost position
boolean stopCondition = false;
System.out.println(Arrays.toString(counters));
while (stopCondition == false) {
if (pivotLocation >= 0 && counterLocation >= 0 && counters[counterLocation] > 0) {
// decrement the rightmost position
counters[counterLocation] = counters[counterLocation] - 1;
System.out.println(Arrays.toString(counters));
} else if (pivotLocation >= 0 && counters[counterLocation] <= 0) {
// the rightmost position has reached zero, so check the pivotPointer
// and decrement if necessary, or move pointer to the left
if (counters[pivotLocation] == 0) {
counters[pivotLocation] = original[pivotLocation];
pivotLocation--;
}
counters[pivotLocation] = counters[pivotLocation] - 1;
counters[counterLocation] = original[counterLocation]; // reset the rightmost position
System.out.println(Arrays.toString(counters));
} else if (Arrays.equals(counters, stopConditionArray)) {
// check if we have reached the solution
stopCondition = true;
} else {
// emergency breakout of infinite loop
stopCondition = true;
}
}
}
}
运行时,可以看到两个明显的问题:
[2, 2, 2]
[2, 2, 1]
[2, 2, 0]
[2, 1, 2]
[2, 1, 1]
[2, 1, 0]
[2, 0, 2]
[2, 0, 1]
[2, 0, 0]
[1, 2, 2]
[1, 2, 1]
[1, 2, 0]
[0, 2, 2]
[0, 2, 1]
[0, 2, 0]
第一,当 pivotPointer 和 currentCountdown 相距超过一个数组单元格时,pivotPointer 不会正确递减。其次,counters[pivotLocation] = counters[pivotLocation] - 1; 行有一个 arrayIndexOutOfBounds,如果已修复,
使算法无法正常运行。
任何帮助将不胜感激。
【问题讨论】:
标签: java arrays algorithm recursion counter