簡體   English   中英

需要幫助將方法從遞歸更改為迭代

[英]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))。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM