Algorithm 动态编程测验或比较两个文本块

Algorithm 动态编程测验或比较两个文本块,algorithm,matrix,dynamic-programming,Algorithm,Matrix,Dynamic Programming,任务定义: 我尝试编写自己的diff-util。我想实现内联搜索 意思是我有两段文字。我必须将第一段(p1)中的字符串压缩到第二段(p2)中的字符串,这样压缩字符串中的常用词之和将是最大的 重要的一点是,你不能替换字符串:我的意思是,如果你将p1[I]收缩到p2[j],那么如果k >,除了它返回 i>代码> > < Max Office < /C> >而不是 Max Office 本身。。现在,您的第一次对齐是next\u best\u i(0,0)和next\u best\u j(0,0)。

任务定义:

我尝试编写自己的diff-util。我想实现内联搜索

意思是我有两段文字。我必须将第一段(p1)中的字符串压缩到第二段(p2)中的字符串,这样压缩字符串中的常用词之和将是最大的

重要的一点是,你不能替换字符串:我的意思是,如果你将p1[I]收缩到p2[j],那么如果k 小例子:

输入:

你有两段:

"Very very very very"         "Very very very"
"bla bla bla"                 "Very very very very very"
"looks like a very dump text" "One more sentence"
"simple text"                 "looks like a peace of ..."
                              "quite simple"
                              "bla bla bla bla"
…和矩阵,其中矩阵[i][j]=字符串p1[i]和p2[j]中的常用字数

3 4 0 0 0 0
0 0 0 0 0 3
0 0 0 3 0 0
0 0 0 0 1 0
输出:

你需要用下一种方式来解释它们:

----------------               "Very very very"
"Very very very very"          "Very very very very very"
"bla bla bla"                  ----------------
----------------               "One more sentence"
"looks like a very dump text"  "looks like a peace of ..."
"simple text"                  "quite simple"
----------------               "bla bla bla bla"
或者,您可以形成下一个矩阵:

(具有构造函数的字符串索引)

p1索引:[0,2,3]
p2索引:[1,3,4]

问题:

此任务的有效算法是什么?

[不必阅读]面临困难:

  • 如何将索引集合传递给下一个迭代:我的意思是您需要在每个迭代中复制所有索引
  • 如果您想使用动态编程,您不仅需要存储一个公共wors编号,还需要为每个可能的迭代存储两个索引集合
  • 解决方案:


    给定数组
    a[m]
    b[n]
    ,并给定一个成本函数:
    benefit(i,j)
    ,它计算元素
    i
    j
    之间的公共字数,您的问题可以表述为
    max\u benefit(i,j)
    这意味着
    i
    j
    是对齐/匹配的,您需要找出剩余部分的最大效益和对齐方式,即:
    max(效益(i+1,j+1)+最大效益(i+2,j+2),效益(i+2,j+1)+最大效益(i+3,j+1),效益(i+3,j+1)+最大效益(i+4,j+1)(i+1,j+2)+最大收益(i+2,j+3),收益(i+1,j+3)+最大收益(i+1,j+4),…)

    现在,当您第一次为任何一对索引计算
    max\u benefit
    时,请存储结果,这样您就不需要重新计算它。也就是说,在计算之前检查您是否有存储值;如果没有,请计算并存储该值

    重新面对困难:

  • 您可以将数组引用作为全局/类成员提供,也可以将数组引用作为两个额外参数传递:例如
    max\u-benefit(i,j,a,b)
    benefit(i,j,a,b)
    。大多数语言都不会复制数组
  • 请看这个答案的主要部分,您只需递归地计算和存储值,这样就不会重新计算

  • 是的,谢谢。但问题是我如何存储答案。随着大数据量的输入,索引集合的长度可以增长到100甚至更多,我不能只为每个可能的迭代存储这样的集合。请参阅我问题的“面临的困难”部分。是的,但如果将相同的集合作为参数传递给方法,它将被更改但你们不需要所有迭代的改变,你们只需要优化迭代的改变。你们明白我的意思吗?我可以给你们一个答案example@NickoleAbs在我的回答中,我只计算了
    max\u效益
    ,而没有计算哪个路线具有最大效益。也就是说,我正在确定答案的一个属性,而不是请回答我自己的问题。让我思考一下答案生成。@ Nigulabs考虑了一个函数<代码> NExtBestBuffi i(i,j)< /Cord>,它类似于<代码> Max Office < /C> >,除了它返回<代码> i>代码> > < <代码> Max Office < /C> >而不是<代码> Max Office 本身。。现在,您的第一次对齐是
    next\u best\u i(0,0)
    next\u best\u j(0,0)
    。假设这些值是
    i1
    j1
    ,您现在可以通过调用
    i2=next\u best\u i(i1,j1)
    j2=next\u best\u j(i1,j1)来计算下一次对齐
    ,等等..有意义吗?很酷,谢谢你发布最终版本。我已经对这个问题投了更高的票,所以不能再问了。PS:现在你明白了,大多数传统术语都使用“成本”而不是“效益”并相应地将其最小化。无需编辑您的解决方案;这只是一个行话提示。要使用术语和
    min
    操作,您需要将矩阵值设置为负值以将其转换为成本。祝您好运!:)抱歉,我不明白这个问题。你所说的对比是什么意思?对比,面对,在你的例子中,把它们相对地放在第一段的最后一串去了哪里“简单文本”。对不起,已经更正了。我在线上有一篇文章系列,介绍了使用最长公共子字符串实现diff算法的一种非常简单的方法,您可以在这里找到:
    public void genConditionLCS() {
        int i = -1;
        int j = -1;
        while (true) {
            int[] indexes = nextIndexes(i+1, j+1);
            i = indexes[0];
            j = indexes[1];
            if (i == -1 || j == -1) break;
            firstParagraphIndexes.add(i); 
            secondParagraphIndexes.add(j);
        }
    }
    private int[] nextIndexes(int i, int j) {
        if ((i > (lcs.length-1)) || (j > (lcs[0].length-1)))
            return new int[] {-1, -1};
        int a = maxBenefit(i + 1, j);
        int b = maxBenefit(i, j + 1);
        int c = maxBenefit(i + 1, j + 1) + lcs[i][j];
        if ((a == 0) && (b == 0) && (c == 0))
            return new int[]{-1, -1};
        else if (a >= b && a >= c)
            return nextIndexes(i+1, j);
        else if (b >= a && b >= c)
            return nextIndexes(i, j+1);
        else //if (c >= a && c >= b)
            return new int[]{i, j};
    }
    
    private int maxBenefit(int i, int j) {
        if ((i > lcs.length - 1) || (j > lcs[0].length - 1)) return 0;
        int res = maxBenefit[i][j];
        if (res == -1) {
            int a = maxBenefit(i + 1, j);
            int b = maxBenefit(i, j + 1);
            int c = maxBenefit(i + 1, j + 1) + lcs[i][j];
            res = max(a, b, c);
            maxBenefit[i][j] = res;
        }
        return res;
    }