需要帮助将方法从递归更改为迭代

Need help changing a method from recursive to iterative

我正在开发一个程序,该程序将在给定数据和正确数据的哈希值的情况下修复数据损坏。即使只处理几个字节的数据,大约 4 或 5 位被损坏后它开始变慢,所以我想我会让它迭代而不是递归。在做了一些研究之后,我发现我可以使用堆栈来做到这一点。我目前无法找到将变量从堆栈中弹出的正确位置。这是原始方法。

private static void fixFile(byte[] data, byte[] hash, byte[] correctHash, MessageDigest hasher, long depth)
{
    int len = data.length;
    outer: for(int i = 0; i < len; i++)
    {
        byte origVal = data[i];
        for(int j = 0; j < 8; j++)
        {
            data[i] = (byte) (data[i] ^ (1 << j));

            if(depth > 1)
                fixFile(data, hash, correctHash, hasher, depth - 1);
            hash = hasher.digest(data);

            if(!Arrays.equals(correctHash, hash))
                data[i] = origVal;
            else
                break outer;
        }
    }
}

这是我尝试使其迭代的修改方法。

private static void fixFile(byte[] data, byte[] hash, byte[] correctHash, MessageDigest hasher, long depth)
{
    Stack stack = new Stack<Integer>();

    int len = data.length;
    outer: for(int i = 0; i < len; i++)
    {
        byte origVal = data[i];
        for(int j = 0; j < 8; j++)
        {
            data[i] = (byte) (data[i] ^ (1 << j));

            if(depth > 1)
            {
                stack.push(depth);
                stack.push(i);
                stack.push(j);
                depth--;
                i = -1;
                j = 0;
                continue outer;
            }
            else
            {
                // where do I put this to make it work.
                j = stack.pop();
                i = stack.pop();
                depth = stack.pop();
            }
            hash = hasher.digest(data);

            if(!Arrays.equals(correctHash, hash))
                data[i] = origVal;
            else
                break outer;
        }
    }
}

我认为你的递归方法是解决这个问题的理想方法,所有时间都将花在摘要函数上。

但是,当您修复深度位时,您可以获得程序速度的阶乘(深度)改进。 (因此对于 6 位,这将使程序运行速度提高 6*5*4*3*2*1 = 720 倍。)

问题是您当前的代码当前会切换数据中的深度位,但顺序不限。即当它切换三个位时,它将尝试切换位 1、2、3 和 2、1、3 和 3、1、2 和 3、2、1 和 1、3、2 和 2、3、1(以及许多其他选项)。请注意,在每种情况下,都会切换完全相同的 3 位,因此没有必要对它们进行全部测试。

您可以通过向您的代码传递附加参数来解决此问题,说明最后一位被切换的位置(即,将 i 和 j 作为 i_base 和 j_base 传递),然后只允许您的代码如果新位位于数据中较晚的位置,则切换新位(即如果 i>i_base || (i==i_base && j>j_base)).