Извлеките разницу между двумя строками в 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";
Я хочу получить то, чего нет в строке прослушивания, которая называется "Hey There\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 "";
}
}
Может ли кто-нибудь помочь?
Ответы
Ответ 1
Google-Diff-матч-патч
Библиотеки Diff Match и Patch предлагают надежные алгоритмы для выполнения операций, необходимых для синхронизации простого текста.
Diff:
Сравните два блока простого текста и эффективно верните список различий.
Совпадение:
По заданной строке поиска найдите лучшее нечеткое совпадение в блоке простого текста. Взвешен как по точности, так и по местоположению.
Patch:
Примените список исправлений к простому тексту. Приложите все усилия, чтобы применить исправление, даже если основной текст не совпадает.
В настоящее время доступны на Java, JavaScript, Dart, C++, С#, Objective C, Lua и Python. Независимо от языка каждая библиотека имеет одинаковый API и одинаковые функциональные возможности. Все версии также имеют комплексные тестовые наборы.
Существует Вики-страница Line или word diffs, которая описывает, как выполнять построчное сравнение.
Ответ 2
Можно использовать StringUtils
из Apache Commons. Вот API-интерфейс StringUtils.
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;
}
Ответ 3
Я нашел 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;
}
Ответ 4
преобразовать строку в списки, а затем использовать следующий метод для получения результата Как удалить общие значения из двух списков массивов
Ответ 5
Если вы предпочитаете не использовать внешнюю библиотеку, вы можете использовать следующий фрагмент кода 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"}
Ответ 6
Я искал какое-то решение, но не смог найти тот, который мне нужен, поэтому я создал класс утилиты для сравнения двух версий текста - новый и старый - и получив текст результата с изменениями между тегами - [добавил] и [ удален]. Его можно легко заменить ярлыком, который вы выбираете вместо этих тегов, например: тег html. string-version-comparison
Любые комментарии будут оценены.
* он может не сработать с длинным текстом из-за большей вероятности нахождения тех же фраз, которые были удалены.
Ответ 7
Вы должны использовать StringUtils от Apache Commons
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
Ответ 8
как насчет этого фрагмента?
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);
}
}
}