gpt4 book ai didi

java - 找到 64 字节数组的所有排列?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:44:03 26 4
gpt4 key购买 nike

我的目标是找到一个 64 字节数组的所有排列,并为每个排列检查在执行函数 F 后是否等于给定的字节数组。

Consider a Small scale Example: Suppose I have 1234, I would like to generate all the permutations of a 4 digit number _ _ _ _ and check each time if it equals 1234

我的第一个想法是实现一个递归函数来生成排列。但是考虑到大小,栈会溢出。

生成所有排列的任何有效方法?鉴于 Java 有大量的库?

最佳答案

如果我没理解错的话,你需要生成所有的64! 64 字节数组的排列,即:

64! = 126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000 排列!

如果每次排列和比较都需要一毫秒(最坏情况下的时间场景)来计算,您将需要:

4023558225072430368576654912961741527234446859923426946943236123009091331506849.3150684931506849315 在一台机器上计算它们! (如果每个排列都需要 100 毫秒,那么这个怪物的第 100 个)。

因此,您应该通过应用一些启发式方法来减少问题的搜索空间,而不是天真地列出所有可能的解决方案。

将搜索空间缩小到更易于处理的数字后,例如:14! (在“一毫秒”的情况下需要 2 年的计算时间),您可以使用 Factoradics 将计算拆分到多台机器上(一个实现 here )计算每台机器的开始和结束排列,然后在每个节点(Knuth's L-algorithm 的一个实现)中使用以下代码在每台机器中搜索解决方案:

public class Perm {
private static byte[] sequenceToMatch;
private static byte[] startSequence;
private static byte[] endingSequence;
private static final int SEQUENCE_LENGTH = 64;

public static void main(String... args) {
final int N = 3;

startSequence = readSequence(args[0]);
endingSequence = readSequence(args[1]);
sequenceToMatch = readSequence(args[2]);

permutations();
}

private static boolean sequencesMatch(byte[] s1, byte[] s2) {
for (int i = 0; i < SEQUENCE_LENGTH; i++) {
if (s1[i] != s2[i]) {
return false;
}
}
return true;
}

private static byte[] readSequence(String argument) {
String[] sBytes = argument.split(",");
byte[] bytes = new byte[SEQUENCE_LENGTH];
int i = 0;
for (String sByte : sBytes) {
bytes[i++] = Byte.parseByte(sByte, 10);
}
return bytes;
}

private static void swap(byte[] elements, int i, int j) {
byte temp = elements[i];
elements[i] = elements[j];
elements[j] = temp;
}

/**
* Reverses the elements of an array (in place) from the start index to the end index
*/
private static void reverse(byte[] array, int startIndex, int endIndex) {
int size = endIndex + 1 - startIndex;
int limit = startIndex + size / 2;
for (int i = startIndex; i < limit; i++) {
// swap(array, i, startIndex + (size - 1 - (i - startIndex)));
swap(array, i, 2 * startIndex + size - 1 - i);
}
}

/**
* Implements the Knuth's L-Algorithm permutation algorithm
* modifying the collection in place
*/
private static void permutations() {
byte[] sequence = startSequence;

if (sequencesMatch(sequence, sequenceToMatch)) {
System.out.println("Solution found!");
return;
}

// For every possible permutation
while (!sequencesMatch(sequence, endingSequence)) {

// Iterate the array from right to left in search
// of the first couple of elements that are in ascending order
for (int i = SEQUENCE_LENGTH - 1; i >= 1; i--) {
// If the elements i and i - 1 are in ascending order
if (sequence[i - 1] < sequence[i]) {
// Then the index "i - 1" becomes our pivot index
int pivotIndex = i - 1;

// Scan the elements at the right of the pivot (again, from right to left)
// in search of the first element that is bigger
// than the pivot and, if found, swap it
for (int j = SEQUENCE_LENGTH - 1; j > pivotIndex; j--) {
if (sequence[j] > sequence[pivotIndex]) {
swap(sequence, j, pivotIndex);
break;
}
}

// Now reverse the elements from the right of the pivot index
// (this nice touch to the algorithm avoids the recursion)
reverse(sequence, pivotIndex + 1, SEQUENCE_LENGTH - 1);
break;
}
}

if (sequencesMatch(sequence, sequenceToMatch)) {
System.out.println("Solution found!");
return;
}
}
}
}

关于java - 找到 64 字节数组的所有排列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29545091/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com