ICU-12450 move com.ibm.icu.impl.Differ to org.unicode.cldr.util.Differ; fork off com.ibm.icu.dev.demo.translit.IntDiffer for use in the translit.Demo

X-SVN-Rev: 38634
This commit is contained in:
Markus Scherer 2016-04-19 22:15:27 +00:00
parent 8d4fe67a1e
commit 56421e3958
2 changed files with 66 additions and 79 deletions

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
* Copyright (C) 1996-2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 1996-2016, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.dev.demo.translit;
@ -42,7 +42,6 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import com.ibm.icu.impl.Differ;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.text.BreakIterator;
import com.ibm.icu.text.CanonicalIterator;
@ -93,9 +92,6 @@ public class Demo extends Frame {
static final String NO_TRANSLITERATOR = "None";
//private static final String COPYRIGHT =
// "\u00A9 IBM Corporation 1999. All rights reserved.";
public static void main(String[] args) {
Frame f = new Demo(600, 200);
f.addWindowListener(new WindowAdapter() {
@ -834,39 +830,51 @@ public class Demo extends Frame {
out.println("<tr><td></td></tr>");
}
static String showDifference(String as, String bs) {
Differ differ = new Differ(300, 3);
StringBuffer out = new StringBuffer();
int max = as.length();
if (max < bs.length()) max = bs.length();
for (int j = 0; j <= max; ++j) {
if (j < as.length()) differ.addA(as.substring(j, j+1));
if (j < bs.length()) differ.addB(bs.substring(j, j+1));
differ.checkMatch(j == max);
IntDiffer differ = new IntDiffer(300, 3);
StringBuilder out = new StringBuilder();
int ia = 0;
int ib = 0;
boolean done;
do {
done = true;
if (ia < as.length()) {
int ca = as.codePointAt(ia);
ia += Character.charCount(ca);
differ.addA(ca);
done = false;
}
if (ib < bs.length()) {
int cb = bs.codePointAt(ib);
ib += Character.charCount(cb);
differ.addB(cb);
done = false;
}
differ.checkMatch(done);
if (differ.getACount() != 0 || differ.getBCount() != 0) {
out.append("...");
if (differ.getACount() != 0) {
out.append("<span class='r'>");
for (int i = 0; i < differ.getACount(); ++i) {
out.append(differ.getA(i));
out.appendCodePoint(differ.getA(i));
}
out.append("</span>");
}
if (differ.getBCount() != 0) {
out.append("<span class='d'>");
for (int i = 0; i < differ.getBCount(); ++i) {
out.append(differ.getB(i));
out.appendCodePoint(differ.getB(i));
}
out.append("</span>");
}
out.append("...");
}
}
} while (!done);
return out.toString();
}
static void showSets(PrintWriter out, Transliterator translit, Transliterator inverse,
UnicodeSet sourceSuper, UnicodeSet targetSuper, int options) {
out.println("<li>Source Set:<ul><li>" + toPattern(closeUnicodeSet(translit.getSourceSet(), options), sourceSuper) + "</li></ul></li>");

View file

@ -1,57 +1,45 @@
/**
*******************************************************************************
* Copyright (C) 1996-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 1996-2016, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.impl;
package com.ibm.icu.dev.demo.translit;
/** VERY Basic Diff program. Compares two sequences of objects fed into it, and
/**
* VERY Basic Diff program. Compares two sequences of ints fed into it, and
* lets you know where they are different.
*
* <p>This version compares ints while the CLDR class Differ compares Objects.
*
* @author Mark Davis
* @version 1.0
*/
final public class Differ<T> {
// public static final String copyright =
// "Copyright (C) 2010, International Business Machines Corporation and others. All Rights Reserved.";
final public class IntDiffer {
/**
* @param stackSize The size of the largest difference you expect.
* @param matchCount The number of items that have to be the same to count as a match
*/
@SuppressWarnings("unchecked")
public Differ(int stackSize, int matchCount) {
public IntDiffer(int stackSize, int matchCount) {
this.STACKSIZE = stackSize;
this.EQUALSIZE = matchCount;
a = (T[]) new Object[stackSize+matchCount];
b = (T[]) new Object[stackSize+matchCount];
a = new int[stackSize+matchCount];
b = new int[stackSize+matchCount];
}
public void add (T aStr, T bStr) {
addA(aStr);
addB(bStr);
}
public void addA (T aStr) {
public void addA(int aStr) {
flush();
a[aCount++] = aStr;
}
public void addB (T bStr) {
public void addB(int bStr) {
flush();
b[bCount++] = bStr;
}
public int getALine(int offset) {
return aLine + maxSame + offset;
}
public T getA(int offset) {
if (offset < 0) return last;
if (offset > aTop-maxSame) return next;
return a[offset];
public int getA(int offset) {
return a[maxSame + offset];
}
public int getACount() {
@ -62,74 +50,68 @@ final public class Differ<T> {
return bTop-maxSame;
}
public int getBLine(int offset) {
return bLine + maxSame + offset;
}
public T getB(int offset) {
if (offset < 0) return last;
if (offset > bTop-maxSame) return next;
return b[offset];
public int getB(int offset) {
return b[maxSame + offset];
}
/**
* Checks for initial & final match.
* To be called after addA() and addB().
* Middle segments that are different are returned via get*Count() and get*().
*
* @param finalPass true if no more input
*/
public void checkMatch(boolean finalPass) {
// find the initial strings that are the same
int max = aCount;
if (max > bCount) max = bCount;
int i;
for (i = 0; i < max; ++i) {
if (!a[i].equals(b[i])) break;
if (a[i] != b[i]) break;
}
// at this point, all items up to i are equal
maxSame = i;
aTop = bTop = maxSame;
if (maxSame > 0) last = a[maxSame-1];
next = null;
if (finalPass) {
aTop = aCount;
bTop = bCount;
next = null;
return;
}
if (aCount - maxSame < EQUALSIZE || bCount - maxSame < EQUALSIZE) return;
// now see if the last few a's occur anywhere in the b's, or vice versa
int match = find (a, aCount-EQUALSIZE, aCount, b, maxSame, bCount);
int match = find(a, aCount-EQUALSIZE, aCount, b, maxSame, bCount);
if (match != -1) {
aTop = aCount-EQUALSIZE;
bTop = match;
next = a[aTop];
return;
}
match = find (b, bCount-EQUALSIZE, bCount, a, maxSame, aCount);
match = find(b, bCount-EQUALSIZE, bCount, a, maxSame, aCount);
if (match != -1) {
bTop = bCount-EQUALSIZE;
aTop = match;
next = b[bTop];
return;
}
if (aCount >= STACKSIZE || bCount >= STACKSIZE) {
// flush some of them
aCount = (aCount + maxSame) / 2;
bCount = (bCount + maxSame) / 2;
next = null;
}
}
/** Convenient utility
* finds a segment of the first array in the second array.
* @return -1 if not found, otherwise start position in b
/**
* Finds a segment of the first array in the second array.
* @return -1 if not found, otherwise start position in bArr
*/
public int find (T[] aArr, int aStart, int aEnd, T[] bArr, int bStart, int bEnd) {
private int find(int[] aArr, int aStart, int aEnd, int[] bArr, int bStart, int bEnd) {
int len = aEnd - aStart;
int bEndMinus = bEnd - len;
tryA:
for (int i = bStart; i <= bEndMinus; ++i) {
for (int j = 0; j < len; ++j) {
if (!bArr[i + j].equals(aArr[aStart + j])) continue tryA;
if (bArr[i + j] != aArr[aStart + j]) continue tryA;
}
return i; // we have a match!
}
@ -138,12 +120,12 @@ final public class Differ<T> {
// ====================== PRIVATES ======================
/** Removes equal prefixes of both arrays. */
private void flush() {
if (aTop != 0) {
int newCount = aCount-aTop;
System.arraycopy(a, aTop, a, 0, newCount);
aCount = newCount;
aLine += aTop;
aTop = 0;
}
@ -151,7 +133,6 @@ final public class Differ<T> {
int newCount = bCount-bTop;
System.arraycopy(b, bTop, b, 0, newCount);
bCount = newCount;
bLine += bTop;
bTop = 0;
}
}
@ -159,14 +140,12 @@ final public class Differ<T> {
private int STACKSIZE;
private int EQUALSIZE;
private T [] a;
private T [] b;
private T last = null;
private T next = null;
// a[] and b[] are equal at 0 to before maxSame.
// maxSame to before *Top are different.
// *Top to *Count are equal again.
private int [] a;
private int [] b;
private int aCount = 0;
private int bCount = 0;
private int aLine = 1;
private int bLine = 1;
private int maxSame = 0, aTop = 0, bTop = 0;
}