滚动输出的文本差异

Text difference of scrolling output

本文关键字:文本 输出 滚动      更新时间:2023-10-16

我有从滚动输出中捕获文本的代码,我正在寻找一种算法(使用C++/Qt),它可以告诉我哪些行是新的注意:新行只会添加到末尾。

因此,在第一次捕获时,我可能会有以下内容:

hello world
some more text
hello world
some text

第二次捕获时可能有:

hello world
some text
yet more text
hello world

所以我想让算法返回,我有两条新行:

yet more text
hello world

如果可能的话,如果它可以从最后一行开始,并在到达已经处理的行后终止,这将有助于性能。但我认为这可能是不可能的,因为可能会有重复的行。

好吧,你说它是滚动的,你正在使用OCR,所以你能在滚动窗口上捕捉滚动小部件的大小,并将其与你记录的行一起检查吗?

或者,你可以将dll挂接到生产者程序中,这样你就可以在它输出新行时发出信号吗?或者直接将其输出导入您的?

对于您的特殊情况,我会考虑一个简单的基本循环内循环算法。我不认为性能真的是一个问题(没有那么多行,我也认为OCR是主要部分),因此算法应该易于阅读和健壮。

伪码中一种可能的算法:

numberOfNewLines = 0
while numberOfNewLines <= numberOfTotalLines do
    compare lines 
        [1..numberOfTotalLines-numberOfNewLines] of textNew
        with lines [1+numberOfNewLines..numberOfTotalLines] of textOld
    if identical then exit while
    numberOfNewLines++
end while

只要一行不同,就可以中断比较,但算法的行数仍然是O(N^2)

然后您可以从textNew的末尾输出最后一个numberOfNewLines。正如评论中提到的,你当然不能检测到一些边缘情况,比如"10000次‘ABC’,然后1次‘DEF’",其中大部分行‘ABC’将被忽略。

我已经针对许多测试用例进行了测试,到目前为止它是有效的:

QStringList scrollDiff(const QStringList& oldLines, const QStringList& newLines)
{
    if (oldLines.empty()) {
        return newLines;
    }
    if (oldLines.size() < newLines.size()) {
        return newLines.mid(oldLines.size());
    }
    /*
     * Note: oldLines.size() == newLines.size()
     */
    int i;
    for (i = 0; i < oldLines.size() && oldLines[i] == newLines[i]; ++i);
    if (i == oldLines.size()) {
        return QStringList();
    }
    // Remove lines from oldLines that are no longer shown
    int j = oldLines.indexOf(newLines[i]);
    if (j == -1) {
        return newLines;
    }
    QStringList commonLines = oldLines.mid(j - i);
    return newLines.mid(commonLines.size());
}