ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java – 查找64字节数组的所有排列?

2019-08-24 19:04:05  阅读:218  来源: 互联网

标签:java arrays algorithm permutation


我的目标是找到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 permutations!

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

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,arrays,algorithm,permutation
来源: https://codeday.me/bug/20190824/1710848.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有