繁体   English   中英

提取Java中两个字符串之间的差异

[英]Extract the difference between two strings in Java

嗨,我有两个字符串:

    String hear = "Hi My name is Deepak"
            + "\n"
            + "How are you ?"
            + "\n"
            + "\n"
            + "How is everyone";
    String dear = "Hi My name is Deepak"
            + "\n"
            + "How are you ?"
            + "\n"
            + "Hey there \n"
            + "How is everyone";

我想获得“嘿那里\\n”的听字符串中不存在的内容。 我找到了一种方法,但在这种情况下失败了:

static String strDiffChop(String s1, String s2) {
    if (s1.length() > s2.length()) {
        return s1.substring(s2.length() - 1);
    } else if (s2.length() > s1.length()) {
        return s2.substring(s1.length() - 1);
    } else {
        return "";
    }
}

任何人都可以帮忙吗?

谷歌差异匹配补丁

Diff Match 和 Patch 库提供了强大的算法来执行同步纯文本所需的操作。

差异:

比较两个纯文本块并有效地返回差异列表。

匹配:

给定一个搜索字符串,在纯文本块中找到它的最佳模糊匹配。 对准确性和位置进行加权。

补丁:

将补丁列表应用于纯文本。 即使底层文本不匹配,也要尽最大努力应用补丁。

目前可用于 Java、JavaScript、Dart、C++、C#、Objective C、Lua 和 Python。 无论使用何种语言,每个库都具有相同的 API 和相同的功能。 所有版本还具有全面的测试工具。

有一个Line 或 word diffs wiki 页面,它描述了如何进行逐行差异。

可以使用Apache Commons 中StringUtils 这是StringUtils API

public static String difference(String str1, String str2) {
    if (str1 == null) {
        return str2;
    }
    if (str2 == null) {
        return str1;
    }
    int at = indexOfDifference(str1, str2);
    if (at == -1) {
        return EMPTY;
    }
 return str2.substring(at);
}
public static int indexOfDifference(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;
}

我已经使用StringTokenizer来找到解决方案。 下面是代码片段

public static List<String> findNotMatching(String sourceStr, String anotherStr){
    StringTokenizer at = new StringTokenizer(sourceStr, " ");
    StringTokenizer bt = null;
    int i = 0, token_count = 0;
    String token = null;
    boolean flag = false;
    List<String> missingWords = new ArrayList<String>();
    while (at.hasMoreTokens()) {
        token = at.nextToken();
        bt = new StringTokenizer(anotherStr, " ");
        token_count = bt.countTokens();
        while (i < token_count) {
            String s = bt.nextToken();
            if (token.equals(s)) {
                flag = true;
                break;
            } else {
                flag = false;
            }
            i++;
        }
        i = 0;
        if (flag == false)
            missingWords.add(token);
    }
    return missingWords;
}

将字符串转换为列表,然后使用以下方法获取结果如何从两个数组列表中删除公共值

如果您不想使用外部库,您可以使用以下 Java 代码段来有效地计算差异:

/**
 * Returns an array of size 2. The entries contain a minimal set of characters
 * that have to be removed from the corresponding input strings in order to
 * make the strings equal.
 */
public String[] difference(String a, String b) {
    return diffHelper(a, b, new HashMap<>());
}

private String[] diffHelper(String a, String b, Map<Long, String[]> lookup) {
    return lookup.computeIfAbsent(((long) a.length()) << 32 | b.length(), k -> {
        if (a.isEmpty() || b.isEmpty()) {
            return new String[]{a, b};
        } else if (a.charAt(0) == b.charAt(0)) {
            return diffHelper(a.substring(1), b.substring(1), lookup);
        } else {
            String[] aa = diffHelper(a.substring(1), b, lookup);
            String[] bb = diffHelper(a, b.substring(1), lookup);
            if (aa[0].length() + aa[1].length() < bb[0].length() + bb[1].length()) {
                return new String[]{a.charAt(0) + aa[0], aa[1]};
            } else {
                return new String[]{bb[0], b.charAt(0) + bb[1]};
            }
        }
    });
}

这种方法是使用动态规划。 它以蛮力的方式尝试所有组合,但记住已经计算的子串,因此在 O(n^2) 中运行。

例子:

String hear = "Hi My name is Deepak"
        + "\n"
        + "How are you ?"
        + "\n"
        + "\n"
        + "How is everyone";
String dear = "Hi My name is Deepak"
        + "\n"
        + "How are you ?"
        + "\n"
        + "Hey there \n"
        + "How is everyone";
difference(hear, dear); // returns {"","Hey there "}

difference("Honda", "Hyundai"); // returns {"o","yui"}

difference("Toyota", "Coyote"); // returns {"Ta","Ce"}

你应该使用 Apache Commons 中的 StringUtils

String diff = StringUtils.difference( "Word", "World" );
System.out.println( "Difference: " + diff );


Difference: ld

资料来源: https : //www.oreilly.com/library/view/jakarta-commons-cookbook/059600706X/ch02s15.html

我正在寻找一些解决方案,但找不到我需要的解决方案,因此我创建了一个实用程序类,用于比较两个版本的文本 - 新的和旧的 - 并通过标签之间的更改获取结果文本 - [添加] 和 [删除]。 它可以轻松地替换为您选择的荧光笔而不是此标签,例如:html 标签。 字符串版本比较

任何意见将不胜感激。

*它可能不适用于长文本,因为找到与删除相同的短语的可能性更高。

https://github.com/google/diff-match-patch外观不错,但是我找不到带有maven的导入jar类型。 谁知道pom配置?

这个片段怎么样?

public static void strDiff(String hear, String dear){
    String[] hr = dear.split("\n");
    for (String h : hr) {
        if (!hear.contains(h)) {
            System.err.println(h);
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM