【问题标题】:Rabin–Karp algorithm for plagiarism implementation by using rolling hashRabin-Karp算法利用滚动哈希实现抄袭
【发布时间】:2011-12-08 21:25:41
【问题描述】:

我正在使用 Rabin–Karp 算法来检查任意两个源代码文件的抄袭情况 所以首先我简单地在c#中实现它的算法,但它的代码在空间O(p)中平均和最佳情况下的运行时间是O(n+m),但最坏情况下的时间是O(nm)。

 public void plagiarism(string [] file1, string [] file2)
    {
        int percent = 0;

        for (int i = 0; i <(file1.Length - file2.Length +1); i++)
        {

            for (int j = 0; j < file1.Length; j++)
            {
                if (file1[i + j - 1] != file2[j])
                {


                }

                    percent++;
                Console.WriteLine(percent);
            }


            Console.WriteLine("not copied");
        }

    }

那么如何通过使用滚动哈希函数来提高效率,因为这比这更好..

【问题讨论】:

  • 你试过什么?换句话说,你的问题到底是什么?您发布了您想使用“滚动哈希函数”..好的..您如何尝试将其转换为那个?你到底遇到了什么问题?
  • 问题是我使用了简单的 robin 算法来检查字符串匹配,但效率不高,所以我想在其中实现滚动哈希函数以提高效率,但是如何??
  • 让我们从一些基础开始:问题是您不知道如何实现“滚动哈希函数”还是您不知道它是什么?
  • 当心,只需重命名变量和函数,您的算法就不会检测到抄袭

标签: c# algorithm data-structures rabin-karp


【解决方案1】:

Wikipedia article 对该算法进行了相当不错的讨论,甚至提到了如何实现滚动散列函数(请参阅“使用散列进行移位子字符串搜索”)。它还解决了如何使用哈希表或布隆过滤器来提高运行时速度。

您还必须了解,最坏的情况是一个相当人为的例子。维基百科文章中给出的示例是“在 1000 万个“a”的字符串中搜索一个由 10,000 个“a”组成的字符串,然后是一个“b”。”

您应该能够使用该 Wikipedia 条目中描述的技术来实现滚动哈希。如果您在实施时遇到问题,请留下一个更具体的问题,说明它是如何完成的,展示您尝试过的内容。

在现实世界的文档中,您不太可能遇到任何接近最坏情况的情况。即使遇到最坏的情况,滚动哈希也不会降低复杂性。实现滚动散列在运行时提供了线性改进,这将被n*m 复杂性所淹没。如果您发现最坏的情况经常发生,那么您可能需要一种不同的算法。

要注意的另一件事是,虽然O(m*n) 可能是个问题,但您必须查看规模。您正在检查的文件有多大?您说您正在使用源代码文件。如果您正在查看典型的课堂项目,那么您可能会谈论 2,000 行代码。这些文件不会展示最坏的情况。即使他们这样做了,n*m 也不会是一个很大的数字。

但是,如果您有 100 个文档,并且您想知道其中一个是否与另一个大量重复,则更大的问题是 O(n^2),因为您必须对照所有其他文档检查每个文档。文档比较次数等于(n*(n-1))/2。如果您希望优化您的流程,您需要一个不同的算法。理想情况下,可以为您提供文档的“指纹”。这样,您可以计算每个文档的指纹一次,然后比较指纹的相似度。

文档指纹识别是一个众所周知的问题。然而,构建一个对比较有用的指纹并不那么简单。你会想研究一种叫做 shingling 的技术。我还看到了一些关于使用小型 Bloom 过滤器(256 字节左右)来表示文档以及使用它进行快速比较的能力的研究。

话虽如此,我怀疑如果您谈论的是一百或两个源代码文件,每个文件可能有 1,000 或 2,000 行长,那么使用良好 Rabin-Carp 实现的天真 O(n^2) 比较技术将做你想做的。这需要一些时间(您将进行 5,000 次单独的文档比较),但我认为 R-K 实施的速度不会成为您的限制因素。

【讨论】:

  • 嗯,我首先阅读了这篇文章,我会从基本的 R.K 算法开始,而不是我肯定更喜欢指纹技术来检查大量文件............ .非常感谢:)
猜你喜欢
  • 1970-01-01
  • 2023-03-09
  • 2017-07-27
  • 2013-12-23
  • 2012-01-18
  • 2018-11-22
  • 2016-09-06
  • 2012-04-09
  • 2021-05-26
相关资源
最近更新 更多