【问题标题】:Need help changing a method from recursive to iterative需要帮助将方法从递归更改为迭代
【发布时间】:2015-04-23 11:29:02
【问题描述】:

我正在开发一个程序,该程序将根据数据和正确数据的哈希值修复数据损坏。即使只处理几个字节的数据,在大约 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;
        }
    }
}

【问题讨论】:

  • 确定它真的有用吗?如果即使是少量比特也很慢,那么看起来算法有问题,而不是实现细节。
  • 我认为它的位数很少,因为它需要在每次更改时重新计算散列。散列算法可能是导致大部分缓慢的原因吗?我在测试时使用的是 md5。

标签: java algorithm recursion stack iteration


【解决方案1】:

我认为您的递归方法非常适合此问题,并且所有时间都将花在摘要函数上。

但是,当您修复深度位时,您可以获得程序速度的阶乘(深度)改进。 (因此对于 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))。

【讨论】:

    猜你喜欢
    • 2017-09-12
    • 1970-01-01
    • 2013-04-15
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    • 2021-01-05
    • 1970-01-01
    相关资源
    最近更新 更多