Skip to content

Instantly share code, notes, and snippets.

@MRezaNasirloo
Created June 19, 2018 11:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MRezaNasirloo/0f616aafb7f5b8c80ece3752a8b2e6e3 to your computer and use it in GitHub Desktop.
Save MRezaNasirloo/0f616aafb7f5b8c80ece3752a8b2e6e3 to your computer and use it in GitHub Desktop.
import android.support.annotation.NonNull;
import org.junit.Test;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import static org.junit.Assert.assertSame;
/**
* A simple implementation to get the characters diff from two strings
* <p>
* It uses java HashSet to boost performance
* <p>
* HashSet has a complexity of O(1) for finding elements, compares to most advance search
* algorithms that has a O(log n) complexity
*/
public class DiffCharTest {
@Test
public void diff_is_correct() throws Exception {
//Given we have 2 strings
String first = "First 1 String";
String second = "Second String";
//When the diff is calculated
Result diff = diff(first, second);
Iterator<Character> iteratorFirst = diff.first.iterator();
Iterator<Character> iteratorSecond = diff.second.iterator();
//Then the result should be
assertSame('F', iteratorFirst.next());
assertSame('s', iteratorFirst.next());
assertSame('1', iteratorFirst.next());
assertSame('e', iteratorSecond.next());
assertSame('c', iteratorSecond.next());
assertSame('o', iteratorSecond.next());
assertSame('d', iteratorSecond.next());
}
private Result diff(String first, String second) {
Set<Character> charactersFirst = createCharSet(first);
Set<Character> charactersSecond = createCharSet(second);
charactersFirst = removeMatch(charactersFirst, second);
charactersSecond = removeMatch(charactersSecond, first);
return new Result(charactersFirst, charactersSecond);
}
/**
* @param charSet the charSet that needs to be cleaned from any match from the given text
* @param text the text which it finds the match from
* @return a charSet without any match from the given text
*/
private Set<Character> removeMatch(Set<Character> charSet, String text) {
for (int i = 0; i < text.length(); i++) {
char charAt = text.charAt(i);
if (charSet.contains(charAt)) {
charSet.remove(charAt);
}
}
return charSet;
}
/**
* Converts a String into a Set of Character
*
* @param text the text that a charSet should be created from
* @return a CharSet from the given text
*/
@NonNull
private Set<Character> createCharSet(String text) {
char[] chars = text.toCharArray();
//LinkedHashSet To preserve order, helps read the outputs easily
Set<Character> charactersFirst = new LinkedHashSet<>(chars.length);
for (char c : chars) {
charactersFirst.add(c);//autobox to Character
}
return charactersFirst;
}
class Result {
final Iterable<Character> first;
final Iterable<Character> second;
Result(Iterable<Character> first, Iterable<Character> second) {
this.first = first;
this.second = second;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment