Android DiffMatchPatch в некоторых случаях неправильный startIndexJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Android DiffMatchPatch в некоторых случаях неправильный startIndex

Сообщение Anonymous »

Моя активность имеет RecyclerView, элементы которого состоят только из EditTexts. Я сделал это для повышения общей производительности по сравнению с одним простым EditText. Эти элементы в начале настроены следующим образом:

Код: Выделить всё

    public void setText(String text) {
List strings = UtilsJava.splitInParts(text, 2000, 50, {'.', ':', '?', '!', ';', ' '});
if (strings.isEmpty()) {
strings.add(text);
}
adapter.setItems(strings);
}

(...)

public static List splitInParts(String str, int len, int m, char[] splitChars) {
List result = new ArrayList();
int cutStart = 0;
for (int i = 0; i < (int) Math.ceil((double) str.length() / len); i++) {
int cutEnd = Math.min(str.length(), (i + 1) * len);
if (cutEnd != str.length() && (cutEnd + m) < str.length()) {
String section = str.substring(cutEnd - m, cutEnd + m);
int index = indexOf(section, splitChars);
cutEnd = cutEnd - m + index + 1;
}
result.add(str.substring(cutStart, cutEnd));
cutStart = cutEnd;
}
return result;
}
Пока все хорошо. В моем примере у меня есть текст, разделенный на 4 элемента. Теперь, например, я хочу удалить часть нулевого элемента, весь второй элемент и часть третьего элемента. Я создал для этого собственное решение (поскольку системное решение не поддерживает несколько EditText). Я просто устанавливаю начальный и конечный индекс простым щелчком мыши. и выберите с помощью конкретной кнопки, какой из них является этим выбором. Теперь, когда у меня есть начальный и конечный индексы, я вызываю функцию HighlightSelection() :

Код: Выделить всё

    public void highlightSelection(int startIndexTotal, int endIndexTotal) {
Predicate predicate1 = o -> o.getStartIndex()  o.getEndIndex() >= startIndexTotal;

int vhIndex = Stream.of(bigTextModelList).filter(predicate1).filter(predicate2).findFirst().get().getVhIndex();
BigTextModel bigTextModel = bigTextModelList.get(vhIndex);

List items = new ArrayList();

int index3 = 0;

if (isSelectionWithinOneVh(startIndexTotal, endIndexTotal, bigTextModel)) {
// it works
} else if (isSelectionWithinMoreVhs(startIndexTotal, endIndexTotal, bigTextModel)) {
int index1;
int index2 = 0;
int totalProcessedLength = 0;
boolean isNoVhIndexChanged = false;
for (BigTextModel bigTextModel1 : bigTextModelList) {
totalProcessedLength += textList.get(bigTextModel1.getVhIndex()).length();

if (bigTextModel1.getVhIndex() == 0) {
index1 = startIndexTotal;
index2 = textList.get(0).length();
String b = getJoinedText().substring(0, index1);
items.add(b);
}

else {
if (totalProcessedLength < endIndexTotal) {
index2 += textList.get(bigTextModel1.getVhIndex()).length();
} else {
if ((textList.get(bigTextModel1.getVhIndex()).length() - Math.abs(totalProcessedLength - endIndexTotal)) > 0) {
index2 += (textList.get(bigTextModel1.getVhIndex()).length() - Math.abs(totalProcessedLength - endIndexTotal));
String item = getJoinedText().substring(index2, index2 + Math.abs(totalProcessedLength - endIndexTotal));
index2 = index2 + Math.abs(totalProcessedLength - endIndexTotal);
items.add(item);
} else if (!isNoVhIndexChanged) {
index2 = index3;
String item = getJoinedText().substring(index2);
items.add(item);
isNoVhIndexChanged = true;
}
}
}
}
}

setItems(items);
}

Код: Выделить всё

    public void setItems(List items) {
textList.clear();
textList.addAll(items);
notifyDataSetChanged();
}
Когда я отлаживал эти элементы, они показались правильными — как я и ожидал, их было 3.
Теперь, например, если я удалю один символ из первого элемента, а затем я удаляю один символ из третьего элемента, а затем при вызове метода getAllDescChanges()

Код: Выделить всё

private LinkedList getAllDescChanges() {

(...)

String savedNoteDesc = bundle.getString("noteDesc");
editedNoteDesc = String.join("", adapter.getTextList());

DiffMatchPatch dmp = new DiffMatchPatch();
return dmp.diff_main(savedNoteDesc, editedNoteDesc);
}
Я получаю 9 изменений, из которых 5-го, 6-го точно не должно быть здесь (потому что 5-е пусто, а 6-е должно быть продолжено как 4-е изменение), а у 7-го неправильный индекс - его startIndex должен быть чем-то вроде 7003. Этот DiffMatchPatch — это проект GitHub отсюда: github_link. Вот снимок экрана отладки этого метода:
Изображение
< /p>
Из того, что я узнал, это следующее:
  • если я удалю только один символ из первого элемента, а затем из последнего элемента без мульти-удаления мульти-текста - DiffMatchPatch показывает все правильно
  • удаление этих двух символов + удаление изнутри индекса 0 - до индекса 1 - нет проблем,
  • удалить эти два символа + удалить из индекса 0 - в индекс 2 - есть проблема,
  • удаление этих двух символов + удаление из индекса 0 в индекс 3 – проблема
Итак, вопрос в том, как избежать этих двух странных изменений и решить проблему с неправильным стартовым индексом 7-го изменения?
Я попробовал:
p>

[*]В функции HighlightSelection() я пробовал работать непосредственно с элементами listItem, устанавливая и удаляя элемент — не сработало

В функции HighlightSelection() я попытался создать новый список и, когда был готов, заменил listItem адаптера этим списком (как в прикрепленном коде)

[*]и некоторые другие неработающие решения, о которых я уже забыл, потому что прошло несколько недель с тех пор, как я начал над ними работать

< /ol>
Если вам нужно что-то еще, спрашивайте.
Я борюсь с этой ошибкой уже несколько недель, но без какого-либо прогресса. Так что огромное вам спасибо, если вы готовы помочь!

Подробнее здесь: https://stackoverflow.com/questions/785 ... some-cases
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»