繁体   English   中英

将递归Diff算法转换为迭代算法的建议?

[英]Advice converting recursive Diff Algorithm to an iterative one?

问候!

我从头开始编写递归diff算法。 它找到两个字符串之间的“最佳匹配”,以便最小化差异,并打印出两个字符串,其中包含CAPS中表示的任何差异。 它“按原样”工作正常,但效率非常低。 我一直在盯着它看了一天半,试图想方设法让它迭代或者至少减少它到达的堆栈深度,但我在我的智慧结束并且希望这里有一个敏锐的头脑会比我更清楚地看到解决方案。

以下是代码的内容。 引用的MergePoint类只是一个简单的“链表”样式节点,其中包含“原始索引”整数,“已更改的索引”整数和“下一个”MergePoint。 MergePoint列表表示每个阵列中已“合并”的一系列索引。 链完成后,链中未表示的任何索引都是插入/删除。 NullObject对象是MergePoint的扩展,回想起来,创建并不是绝对必要的,并且基本上可以被认为是常规的'null'。

任何建议/意见将非常感谢。

public class StringCompare 
{
    public static int[][]       mergeList       = new int[0][0];
    public static MergePoint    NULL            = NullObject.getNull();
    public static int           maxMerged       = 0;
    public static int           minClusterSize  = -1;

    public static void diff(String orig, String alt)
    {
        String[] original = orig.toUpperCase().split(" ");
        String[] altered  = alt.toUpperCase().split(" ");

        for(int i = 0; i < altered.length; i++)
        {
            merge(original, altered, 0, i, NULL, NULL, 0, 0);
        }


        for(int i = 0; i < mergeList.length; i++)
        {
            or[mergeList[i][0]] = or[mergeList[i][0]].toLowerCase();
            al[mergeList[i][1]] = al[mergeList[i][1]].toLowerCase();
        }

        printStringArray(or);
        printStringArray(al);
    }

    private void printStringArray(String[] arr)
    {
        for(String word : arr)
        {
            System.out.print(word.trim() + " ");
        }

        System.out.println();
    }

    private static void merge(String[] original, String[] altered, int indexInOriginal, int indexInAltered, MergePoint head, MergePoint tail, int listSize, int clusters)
    {
        if (indexInOriginal >= original.length)
        {           
            if (listSize > 0)
            {
                if (((listSize == maxMerged) && (clusters < minClusterSize)) ||
                    (listSize > maxMerged))
                {
                    storeMergePoints(head, listSize, clusters);
                }
            }
        }
        else if (indexInAltered >= altered.length)
        {
            if (tail != NULL)
            {
                merge(original, altered, (indexInOriginal + 1), (tail.indexInNew() + 1), head, tail, listSize, clusters);
            }
            else
            {
                merge(original, altered, (indexInOriginal + 1), 0, head, tail, listSize, 0);
            }
        }
        else
        {
            if(original[indexInOriginal].equals(altered[indexInAltered]))
            {
                MergePoint  mergePoint  = new MergePoint(indexInOriginal, indexInAltered);
                MergePoint  bookMark    = NULL;             
                int         newClusters = clusters;

                if (indexInOriginal != (tail.indexInOriginal() + 1))
                {
                    newClusters++;
                }

                if (indexInAltered != (tail.indexInNew() + 1))
                {
                    newClusters++;
                }

                if (head == NULL)
                {
                    head = mergePoint;
                    tail = head;
                }
                else
                {
                    tail.setNext(mergePoint);

                    bookMark    = tail;                 
                    tail        = tail.next();
                }

                merge(original, altered, (indexInOriginal + 1), (indexInAltered + 1), head, tail, (listSize + 1), newClusters);

                if (bookMark == NULL)
                {
                    merge(original, altered, indexInOriginal, (indexInAltered + 1), NULL, NULL, 0, 0);
                }
                else
                {
                    bookMark.setNext(NULL);

                    merge(original, altered, indexInOriginal, (indexInAltered + 1), head, bookMark, listSize, newClusters);
                }
            }
            else
            {
                merge(original, altered, indexInOriginal, (indexInAltered + 1), head, tail, listSize, clusters);
            }
        }
    }

    public static void storeMergePoints(MergePoint current, int size, int clusters)
    {       
        mergeList       = new int[size][2];
        maxMerged       = size;
        minClusterSize  = clusters;

        for(int i = 0; i < size; i++)
        {
            mergeList[i][0] = current.indexInOriginal();
            mergeList[i][1] = current.indexInNew();
            current         = current.next();
        }       
    }
}

要使用迭代替换递归,您可以考虑使用您控制的堆栈对象替换JVM堆栈:java.util.Stack非常适合这种情况。 只需在每次迭代时在该堆栈上推送()和pop(),而不是让方法调用自身。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM