我在课堂上编写程序遇到了麻烦:
给定一个偶数长度数组和成对有效性测试,我必须将数组元素分成对,每个元素都通过有效性测试。因此,我最初可能会比较array[0]
和array[1]
,如果无效,则比较array[0]
和array[2]
等。
例如,如果输入数组的长度为6且元素为{0, 1, 2, 3, 4, 5}
,则有效的整体结果可能为{{0,2}, {1,3}, {4,5}}
,其中原始数组的每个元素只出现一次,每对根据有效性测试方法有效。
我不知道如何继续。
答案 0 :(得分:1)
编辑:你可以拥有这样的东西。
从$ ./s3
sizeof test : 40
myint : 0 0
mychar : 4 4
myptr : 8 8
myarr : 16 16
myuint : 32 32
移除位置a
和b
中元素的辅助方法。
origin
你最后的方法。您可以创建自己的例外。当数组的第一个元素没有遇到有效对时,抛出此异常。这是实现回溯的一种方式。在调用private static int[] remove(int[] origin, int a, int b) {
int[] result = new int[origin.length - 2];
int i = 0;
for (int j = 0; j < origin.length; j++) {
if (j != a && j != b) {
result[i] = origin[j];
i++;
}
}
return result;
}
时,可以抛出此异常。因此,在获得调用结果后,yourProblem(remove(array, 0, i))
被添加到arrayList中(这意味着,遇到了解决方案,并且没有抛出任何异常)。请注意递归已实施。
validPar
答案 1 :(得分:1)
我不会为你写作业,但我会尽力让你朝着有希望的方向前进。
您可以采用的一种方法是检查整个输入数组的所有可能排序,直到找到每个连续元素对有效的顺序。长度为n!
的数组有n
个排序,因此这种排序非常差。它还会多次测试多对,并且通常不使用已经执行的有效性测试来缩小可能的解决方案空间。但是如果你已经知道如何枚举排列,那么它的优势就是不需要更多的东西。
另一个通用途径是一次构建一对解决方案,这似乎是您在问题中描述的一般方法。如果你不需要担心回溯,这种方法会更容易,但回溯要求并不是一个杀手。
您可以使用嵌套循环扫描元素对,通常如另一个答案中所述。那么,第一个技巧是使用每个元素一次。一种方法是使用交换数组元素来形成对,以便在找到每对之后剩余的未配对元素都在数组的尾端。这使得回溯有点棘手,但并非不可能 - 第二个技巧是在需要时反转交换。这适用于递归实现,可能具有以下形式:
/**
* Attempts to rearrange the elements of a tail of array, starting at index
* start, so that each consecutive element pair satisfies the validity criterion.
* If unsuccessful, restores the array elements to their initial order before
* returning.
*
* @param array the array whose elements are to be paired
* @param start the index of the first element of the tail
* @return true if and only if the elements of the tail were successfully paired
*/
boolean formPairs(int array[], int start) {
// ...
}
递归的入口点通常是将0
作为起始索引。只要start + 1
大于或等于数组长度(成功!),或者没有与元素array[start]
形成对(失败),递归就会终止。
还有其他变化,但似乎不太可能在你的表面水平上出现比上述更复杂的事情。