2016-07-14 47 views
-3

在Java中,我期望獲得兩個字符串之間差異的所有開始和結束索引列表。我看到如何獲得兩個字符串之間第一個區別的起始索引,但我無法完全弄清楚如何完成這個問題。我發現在StringUtils中的代碼:indexOfDifference(String,String),它獲取兩個字符串之間的第一個區別的起始索引,但我沒有看到一種方法來獲得第一個區別的結束索引,也不會看到一種方式來獲得所有其他的兩個字符串之間所有差異的開始/結束索引。如何獲得Java中兩個字符串之間所有差異的開始/結束索引?

舉例來說,如果我有這兩個字符串: origStr:「Hello World」的 revisedStr:「幫助World23」

我想要的原稿和修訂可疑交易報告之間的差異的所有範圍。

任何指導將非常有幫助。

這是我到目前爲止的代碼:

import difflib.*; 

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 
import java.net.URL; 
import java.util.LinkedList; 
import java.util.List; 

public class TestDiffUtils { 

    public TestDiffUtils() { 

    } 

    // Helper method to read the files to compare into memory, convert them to a list of Strings which can be used by the DiffUtils library for comparison 
    private static List fileToLines(String filename) { 
     List lines = new LinkedList(); 
     String line; 
     try { 
      URL path = TestDiffUtils.class.getResource(filename); 
      File f = new File(path.getFile()); 
      BufferedReader in = new BufferedReader(new FileReader(f)); 
      while ((line = in.readLine()) != null) { 
       lines.add(line); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return lines; 
    } 

    private static void printUnifiedDiffs(List<String> diffs){ 
     for(String diff : diffs){ 
      System.out.println(diff); 
     } 
    } 

    /** 
    * Compares two Strings, and returns the index at which the 
    * Strings begin to differ. 
    * 
    * For example, 
    * <code>indexOfDifference("i am a machine", "i am a robot") -> 7</code> 
    * 
    * <pre> 
    * StringUtils.indexOfDifference(null, null) = -1 
    * StringUtils.indexOfDifference("", "") = -1 
    * StringUtils.indexOfDifference("", "abc") = 0 
    * StringUtils.indexOfDifference("abc", "") = 0 
    * StringUtils.indexOfDifference("abc", "abc") = -1 
    * StringUtils.indexOfDifference("ab", "abxyz") = 2 
    * StringUtils.indexOfDifference("abcde", "abxyz") = 2 
    * StringUtils.indexOfDifference("abcde", "xyz") = 0 
    * </pre> 
    * 
    * @param str1 the first String, may be null 
    * @param str2 the second String, may be null 
    * @return the index where str2 and str1 begin to differ; -1 if they are equal 
    * @since 2.0 
    */ 
    public static int startingIndexOfDifference(String str1, String str2) { 
     if (str1 == str2) { 
      return -1; 
     } 
     if (str1 == null || str2 == null) { 
      return 0; 
     } 
     int i; 
     for (i = 0; i < str1.length() && i < str2.length(); ++i) { 
      if (str1.charAt(i) != str2.charAt(i)) { 
       break; 
      } 
     } 
     if (i < str2.length() || i < str1.length()) { 
      return i; 
     } 
     return -1; 
    } 

    private static void doBasicLineByLineDiff(Boolean doLargeFileTest) { 
     String origFileName; 
     String revisedFileName; 

     if(doLargeFileTest) 
     { 
      origFileName = "test_large_file.xml"; 
      revisedFileName = "test_large_file_revised.xml"; 
     }else{ 
      origFileName = "originalFile.txt"; 
      revisedFileName = "revisedFile.txt"; 
     } 

     List<String> originalLines = fileToLines(origFileName); 
     List<String> revisedLines = fileToLines(revisedFileName); 

     Patch patch = DiffUtils.diff(originalLines, revisedLines); 
     List<String> diffs = DiffUtils.generateUnifiedDiff(origFileName, revisedFileName, originalLines, patch, 0);  // 0 = don't show any lines of context around different lines 
     List<Delta> deltas = patch.getDeltas(); 
     for(Delta delta : deltas){ 
      int diffLine = delta.getOriginal().getPosition()+1; 
      System.out.println("[" + diffLine + " : (" + startingIndexOfDifference((String) delta.getOriginal().getLines().get(0), (String) delta.getRevised().getLines().get(0)) + ",<todo-diffEndIndexHere>)]"); 
     } 

     // printUnifiedDiffs(diffs); 
    } 

    public static void main(String[] args) { 
     doBasicLineByLineDiff(false); 
    } 
} 
+0

[你有什麼嘗試不行](http://whathaveyoutried.com)? – ManoDestra

+1

編輯顯示我迄今爲止的代碼。我可以得到第一個差異的起始索引,但是我需要兩個字符串之間所有差異的索引範圍。 –

+0

我覺得你可以遞歸地做到這一點。 – jordaniac89

回答

1

DiffUtils.diff()需要List<?>,你把它用線(List<String>)找到行的差異。

您可以重新使用它來查找兩行之間的字符差異,即List<Character>

它已經具有識別差異結束的所有複雜性,並且重複性地重新開始共同性。當你已經有一個可以做到的圖書館時,不要試圖自己實現它。

+0

非常感謝。由於DiffUtils類中的一些名稱,我錯過了這個小細節。安德烈亞斯指出,有時最簡單的解決方案是最好的解決方案。 –