I went through your code, and your logic for string matching makes sense to me. It registers ChangeStart , NewChangeEnd and OldChangeEnd , and the algorithm works fine. You just want to find out if an insert , delete, or replacement has occurred. Here is how I would do it.
First of all, you need to make sure that after you get the first point of an incorrect match, i.e. ChangeStart , when you cross lines from the end, the index should not cross ChangeStart .
I will give you an example. Consider the following lines:
var NewText = "Hello Worllolds!"; var OldText = "Hello Worlds!"; ChangeStart -> 10
In this case, the problem is when it starts to match from the back, the flow looks something like this:
Comparing end: 1(N: 12 O: 12: ! -> !) 2(N: 11 O: 11: s -> s) 3(N: 10 O: 10: d -> d) -> You need to stop here! //Although there is not a mismatch, but we have reached ChangeStart and //we have already established that characters from 0 -> ChangeStart-1 match //That is why it outputs "lo" instead of "lol"
Assuming what I just said makes sense, you just need to change your for loops as follows:
if (NewText.length > OldText.length) { for (var i = 1; i < NewText.length && ((OldText.length-i)>=ChangeStart); i++) { ... NewChangeEnd = NewText.length - i -1; OldChangeEnd = OldText.length - i -1; if(//Mismatch condition reached){ //break..That code is fine. } }
This condition โ (OldText.length-i)>=ChangeStart takes care of the anomaly that I mentioned, and therefore the for loop automatically terminates if this condition is reached. However, as I already mentioned, situations may arise when this condition is reached before an incorrect match is met, as I just demonstrated. So you need to update the values โโof NewChangeEnd and OldChangeEnd as 1 less than the match . In the event of an incorrect match, you save the values โโaccordingly.
Instead of else -if we could simply wrap these two conditions in a situation where we know that NewText.length > OldText.length definitely not true, i.e. it is either a replacement or a removal . Again NewText.length > OldText.length also means that it can be a replacement or insert according to your examples, which makes sense. So else might look something like this:
else { for (var i = 1; i < OldText.length && ((OldText.length-i)>=ChangeStart); i++) { ... NewChangeEnd = NewText.length - i -1; OldChangeEnd = OldText.length - i -1; if(//Mismatch condition reached){ //break..That code is fine. } }
If you have understood the minor changes so far, identifying specific cases is very simple:
- Delete - Condition โ
ChangeStart > NewChangeEnd . ChangeStart -> OldChangeEnd row from ChangeStart -> OldChangeEnd .
Remote text - OldText.substring(ChangeStart, OldChangeEnd + 1);
- Insert - Condition โ
ChangeStart > OldChangeEnd . Insert a row into ChangeStart .
Nested text - NewText.substring(ChangeStart, NewChangeEnd + 1);
- Replacement . If
NewText != OldText and the two conditions above are not , then there is a replacement.
The text in the old line that was replaced โ OldText.substring(ChangeStart, OldChangeEnd + 1);
NewText.substring(ChangeStart, NewChangeEnd + 1); text - NewText.substring(ChangeStart, NewChangeEnd + 1);
Start and end positions in OldText that got replaced โ ChangeStart -> OldChangeEnd
I created a jsfiddle containing the changes I mentioned in your code. You can check it out. Hope you start in the right direction.