3

Markdown 形式でのプログラミングに関するテキストがたくさんあります。これらのテキストを Word/HTML に変換できるビルド プロセスがあり、スペル チェックやドキュメントにヘッダー構造が必要かどうかのチェックなどの簡単な検証ルールも実行できます。そのビルド コードを拡張して、すべてのテキスト内のコピー アンド ペーストまたは同様のチャンクもチェックしたいと考えています。

その分析に役立つ既存の Java/Groovy ライブラリはありますか?

私の最初のアイデアは、PMD の CopyPasteDetector を使用することでしたが、実際のコードを分析するには指向性が高すぎます。通常のテキストを分析するためにそれを使用する方法がわかりません。

4

3 に答える 3

2

Dudeを試してみるのもいいかもしれません。これは、私自身のテキスト ファイル用の迅速で汚い重複検出ツールです。2 つのテキスト ファイル間でどれだけ共有されているかを簡単に見積もることができるだけでなく、一連のファイル間でのコピーを判断して、共有関係の優れたグラフを描画することもできます。

于 2013-07-06T17:13:11.790 に答える
2

結局、CPD と Groovy を使用することになりました。誰かが興味を持っている場合のコードは次のとおりです。

import net.sourceforge.pmd.cpd.Tokens
import net.sourceforge.pmd.cpd.TokenEntry
import net.sourceforge.pmd.cpd.Tokenizer
import net.sourceforge.pmd.cpd.CPDNullListener
import net.sourceforge.pmd.cpd.MatchAlgorithm
import net.sourceforge.pmd.cpd.SourceCode
import net.sourceforge.pmd.cpd.SourceCode.StringCodeLoader
import net.sourceforge.pmd.cpd.SimpleRenderer

// Prepare empty token data.
TokenEntry.clearImages()
def tokens = new Tokens()

// List all source files with text.
def source = new TreeMap<String, SourceCode>()
new File('.').eachFile { file ->
  if (file.isFile() && file.name.endsWith('.txt')) {
    def analyzedText = file.text
    def sourceCode = new SourceCode(new StringCodeLoader(analyzedText, file.name))
    source.put(sourceCode.fileName, sourceCode)
    analyzedText.eachLine { line, lineNumber ->
      line.split('[\\W\\s\\t\\f]+').each { token ->
        token = token.trim()
        if (token) {
          tokens.add(new TokenEntry(token, sourceCode.fileName, lineNumber + 1))
        }
      }
    }
    tokens.add(TokenEntry.getEOF())
  }
}

// Run matching algorithm.
def maxTokenChain = 15
def matchAlgorithm = new MatchAlgorithm(source, tokens, maxTokenChain, new CPDNullListener())
matchAlgorithm.findMatches()

// Produce report.
matchAlgorithm.matches().each { match ->
  println "  ========================================"
  match.iterator().each { mark ->
    println "  DUPLICATION ERROR: <${mark.tokenSrcID}:${mark.beginLine}> [DUPLICATION] Found a ${match.lineCount} line (${match.tokenCount} tokens) duplication!"
  }
  def indentedTextSlice = ""
  match.sourceCodeSlice.eachLine { line ->
    indentedTextSlice += "  $line\n"
  }
  println "  ----------------------------------------"
  println indentedTextSlice
  println "  ========================================"
}
于 2013-07-15T19:54:21.853 に答える
1

2 つの文字列に対する単純な実装のLongest Common Substring (LCS)アルゴリズムから始めることができます。1 つのJava 実装を参照してください。

次に、Suffix ArraysGenetics and string algorithmが表示されます。

大きなテキストの最長共通部分文字列も参照してください。

于 2013-07-06T18:07:49.067 に答える