【问题标题】:Diff between two files两个文件之间的差异
【发布时间】:2023-04-04 02:43:01
【问题描述】:

我正在寻找执行以下操作的 sn-p 代码:

给定两个代表两个文件的字符串列表

例如,

  • FILE1 = {“SSome”、“SSimple”、“TText”、“FFile”}
  • FILE2 = {“AAnother”、“TText”、“FFile”、“WWith”、“AAdditional”、“LLines”}

如果我调用 diff(file1,file2)

输出将是 FILE1 和 FILE2 之间的差异:

  1. *SSome|另一个
  2. -SSimple
  3. TText
  4. F 文件
  5. +W带
  6. +A附加
  7. +LLines

非常感谢!

【问题讨论】:

  • 不知道我理解你的 q,但也许你 wqnt 大的“文件”字符串。与较小的“文件”中的每个字符串进行比较并打印差异?一点点sreaching,你就会碰到函数String.equals来比较两个字符串
  • 其他一切都有道理,但*Some|Another的逻辑是什么
  • 您可以只解析文件,将行添加到单独的集合中,然后通过集合的差异和其他集合操作来找出不同之处。到目前为止,您尝试过什么?

标签: java string file diff


【解决方案1】:

我从您的问题中收集到以下信息:

  • *word1|word2 - 表示文件 1 中的单词在文件 2 中已更改
  • -word - 表示文件 1 中的单词已删除文件 2
  • word - 表示文件 1 中的单词在文件 2 中保持不变
  • +word - 表示该单词最初不在文件 1 中,但已添加到文件 2 中

我认为文件 1 是“源”文件,文件 2 是我们展示这些差异的“目标”文件。话虽如此,试试这个算法(它对DiffNow 并不完美,但它非常接近):

public static void main(String[] args) throws Exception {
    List<String> file1 = new ArrayList(Arrays.asList("Some", "Simple", "Text", "File"));
    List<String> file2 = new ArrayList(Arrays.asList("Another", "Text", "File", "With", "Additional", "Lines"));

    boolean diff = false;
    int file2Index = 0;
    for (int file1Index = 0; file1Index < file1.size();) {
        if (!file1.get(file1Index).equals(file2.get(file2Index)) && !diff) {
            diff = true;
            // The word from file 1 was changed
            System.out.println("*" + file1.get(file1Index) + "|" + file2.get(file2Index));
            file1Index++;
            file2Index++;
        } else if (!file1.get(file1Index).equals(file2.get(file2Index)) && diff) {
            // This word was removed from file 1
            System.out.println("-" + file1.get(file1Index));
            file1Index++;
        } else {
            System.out.println(file1.get(file1Index));
            diff = false;
            file1Index++;
            file2Index++;
        }
    }

    // Print what's left from file 2
    for (; file2Index < file2.size(); file2Index++) {
        System.out.println("+" + file2.get(file2Index));
    }
}

结果:

*Some|Another
-Simple
Text
File
+With
+Additional
+Lines

【讨论】:

  • word1|word2 - 表示第一个文件的第一个单词已更改为第二个文件的 word2。这是让我卡住的最难的部分,我认为我需要使用某种 > 并推送单词,直到找到下一个单词(在本例中为 'Text' 单词)然后向后退(放“- WORD") 直到第一种情况,我应该把 ""
  • @JessiPerotti 好的,我已根据您的要求更新了答案。我假设如果第一个单词不同打印“*word1|word2”,否则它会打印“word1”
  • 这不仅仅是在第一个单词的情况下。这就是我的意思prntscr.com/7xu345
  • @JessiPerotti 感谢您的屏幕截图。我认为更新的答案就是你正在寻找的。我会发布该图片或解释您问题中的差异结果。
【解决方案2】:

这是我尝试过的。

import java.util.*;

public class SetDemo
{
    public static void main(String[] args){
        String[] file1 = new String[]{"Some", "Simple", "Text", "File"};
        String[] file2  = new String[]{"Another", "Text", "File", "With", "Additional", "Lines"};
        Set<String> set1 = new HashSet<String>();
        Set<String> set2 = new HashSet<String>();

        for(String s: file1)
            {
                set1.add(s);
            }

        for(String s2: file2)
            {
                set2.add(s2);
            }

        Set<String> s1intercopy = new HashSet<String>(set1);
        Set<String> s2intercopy = new HashSet<String>(set2);

        s1intercopy.retainAll(s2intercopy); //Finds the intesection                                                                                                                                                                                                                  

        Set<String> s1symdiffcopy = new HashSet<String>(set1);
        Set<String> s2symdiffcopy = new HashSet<String>(set2);

        s1symdiffcopy.removeAll(set2);
        s2symdiffcopy.removeAll(set1);

        int count = 0;
        for(String s7: s1intercopy){
            count++;
            System.out.println(Integer.toString(count)+'.'+s7);
        }
        if (set1.size() > set2.size())
        {
            for(String s3: s1symdiffcopy){
                count++;
                System.out.println(Integer.toString(count)+'.'+'+'+s3);
            }
            for(String s4: s2symdiffcopy){
                count++;
                System.out.println(Integer.toString(count)+'.'+'-'+s4);
            }
        }else if (set2.size() > set1.size())
        {
            for(String s5: s2symdiffcopy){
                count++;
                System.out.println(Integer.toString(count)+'.'+'+'+s5);
            }
            for(String s6: s1symdiffcopy){
                count++;
                System.out.println(Integer.toString(count)+'.'+'-'+s6);
            }
        }

    }
}

输出:

1.Text
2.File
3.+Lines
4.+Additional
5.+Another
6.+With
7.-Some
8.-Simple

我不确定您所说的*Some|Another 是什么意思,但上面的代码所做的只是找到集合之间的交集和对称差异,确定哪个集合更大,然后将“+”分配给哪个值是较大集合的一部分,而“-”是较小集合的一部分。我没有从文件中读取以节省时间,但这部分很容易,你可以查一下。根据您的输出,您似乎正在搜索一个文件,并且该文件中的每个字符串都在搜索另一个文件。这对于大文件来说效率很低,所以我相信上述解决方案通过将其保存到集合中并执行集合操作来优化它。

【讨论】:

    猜你喜欢
    • 2017-02-14
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 2021-01-01
    • 1970-01-01
    • 2010-11-23
    相关资源
    最近更新 更多