Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,7 @@ public class Damerau implements MetricStringDistance {
*/
public final double distance(final String s1, final String s2) {

if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,7 @@ public Jaccard() {
* @throws NullPointerException if s1 or s2 is null.
*/
public final double similarity(final String s1, final String s2) {
if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 1;
Expand Down
29 changes: 16 additions & 13 deletions src/main/java/info/debatty/java/stringsimilarity/JaroWinkler.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@ public class JaroWinkler
implements NormalizedStringSimilarity, NormalizedStringDistance {

private static final double DEFAULT_THRESHOLD = 0.7;
private static final int THREE = 3;
private static final double JW_COEF = 0.1;
private static final int IDX_MATCHES = 0;
private static final int IDX_TRANSPOSITIONS = 1;
private static final int IDX_PREFIX = 2;
private static final int IDX_MAX_LEN = 3;
private static final double JW_COEF = 0.1;
private static final int JARO_DIVISOR = 3;

private final double threshold;

/**
Expand Down Expand Up @@ -62,29 +67,27 @@ public final double getThreshold() {
* @throws NullPointerException if s1 or s2 is null.
*/
public final double similarity(final String s1, final String s2) {
if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 1;
}

int[] mtp = matches(s1, s2);
float m = mtp[0];
float m = mtp[IDX_MATCHES];
if (m == 0) {
return 0f;
}
double j = ((m / s1.length() + m / s2.length() + (m - mtp[1]) / m))
/ THREE;
double j = ( m / s1.length()
+ m / s2.length()
+ (m - mtp[IDX_TRANSPOSITIONS]) / m
) / JARO_DIVISOR;

double jw = j;

if (j > getThreshold()) {
jw = j + Math.min(JW_COEF, 1.0 / mtp[THREE]) * mtp[2] * (1 - j);
jw = j + Math.min(JW_COEF, 1.0 / mtp[IDX_MAX_LEN])
* mtp[IDX_PREFIX] * (1 - j);
}
return jw;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,7 @@ public final double distance(final String s1, final String s2) {
*/
public final double distance(final String s1, final String s2,
final int limit) {
if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 0;
Expand Down Expand Up @@ -111,8 +105,7 @@ public final double distance(final String s1, final String s2,
return limit;
}

// copy v1 (current row) to v0 (previous row) for next iteration
//System.arraycopy(v1, 0, v0, 0, v0.length);


// Flip references to current and previous row
vtemp = v0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,7 @@ public class LongestCommonSubsequence implements StringDistance {
* @throws NullPointerException if s1 or s2 is null.
*/
public final double distance(final String s1, final String s2) {
if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,7 @@ public class MetricLCS
* @throws NullPointerException if s1 or s2 is null.
*/
public final double distance(final String s1, final String s2) {
if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 0;
Expand Down
8 changes: 1 addition & 7 deletions src/main/java/info/debatty/java/stringsimilarity/NGram.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,7 @@ public NGram() {
* @throws NullPointerException if s0 or s1 is null.
*/
public final double distance(final String s0, final String s1) {
if (s0 == null) {
throw new NullPointerException("s0 must not be null");
}

if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}
StringUtils.requireNonNull(s0, s1);

if (s0.equals(s1)) {
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,7 @@ public class NormalizedLevenshtein implements
*/
public final double distance(final String s1, final String s2) {

if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,7 @@ public final class OptimalStringAlignment implements StringDistance {
* @throws NullPointerException if s1 or s2 is null.
*/
public double distance(final String s1, final String s2) {
if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 0;
Expand Down
8 changes: 1 addition & 7 deletions src/main/java/info/debatty/java/stringsimilarity/QGram.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,7 @@ public QGram() {
* @throws NullPointerException if s1 or s2 is null.
*/
public final double distance(final String s1, final String s2) {
if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,7 @@ public class RatcliffObershelp implements
*/
@Override
public final double similarity(final String s1, final String s2) {
if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 1.0d;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public ShingleBased(final int k) {
/**
*
*/
ShingleBased() {
protected ShingleBased() {
this(DEFAULT_K);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,7 @@ public SorensenDice() {
* @throws NullPointerException if s1 or s2 is null.
*/
public final double similarity(final String s1, final String s2) {
if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 1;
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/info/debatty/java/stringsimilarity/StringUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package info.debatty.java.stringsimilarity;

/**
* Shared validation helpers for all similarity/distance methods.
*/


public class StringUtils {
private StringUtils() {} // utility class β€” no instantiation


static void requireNonNull(String s1, String s2) {
if (s1 == null) throw new NullPointerException("s1 must not be null");
if (s2 == null) throw new NullPointerException("s2 must not be null");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,7 @@ public final double distance(final String s1, final String s2) {
*/
public final double distance(final String s1, final String s2,
final double limit) {
if (s1 == null) {
throw new NullPointerException("s1 must not be null");
}

if (s2 == null) {
throw new NullPointerException("s2 must not be null");
}
StringUtils.requireNonNull(s1, s2);

if (s1.equals(s2)) {
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
package info.debatty.java.stringsimilarity.experimental;

import info.debatty.java.stringsimilarity.interfaces.StringDistance;

import java.util.Iterator;
import java.util.LinkedList;

/**
Expand Down Expand Up @@ -62,34 +64,52 @@ public final void setMaxOffset(final int max_offset) {
* @param s2
* @return
*/

// AFTER β€” Offset moved to private static nested class
private static final class Offset {
final int c1;
final int c2;
boolean trans; // mutable β€” documented intentionally
Offset(int c1, int c2, boolean trans) {
this.c1 = c1; this.c2 = c2; this.trans = trans;
}
}

/** Validates that neither string is null, consistent with all other algorithms. */
private static void validateInputs(String s1, String s2) {
if (s1==null) throw new NullPointerException("s1 must not be null/NULL");
if (s2==null) throw new NullPointerException("s2 must not be null/NULL"); // added null handling
}

/** Resolves whether a new match at (c1, c2) is a transposition. */
private boolean resolveTransposition(
int c1, int c2, LinkedList<Offset> offsetArr, int[] trans) {
boolean isTrans = false;
Iterator<Offset> it = offsetArr.iterator();
while (it.hasNext()) {
Offset ofs = it.next();
if (c1 <= ofs.c1 || c2 <= ofs.c2) {
isTrans = Math.abs(c2 - c1) >= Math.abs(ofs.c2 - ofs.c1);
if (isTrans) { trans[0]++; }
else if (!ofs.trans) { ofs.trans = true; trans[0]++; }
break;
} else if (c1 > ofs.c2 && c2 > ofs.c1) { it.remove(); }
}
return isTrans;
}

public final double distance(final String s1, final String s2) {

/**
* Used to store relation between same character in different positions
* c1 and c2 in the input strings.
*/
class Offset {

private final int c1;
private final int c2;
private boolean trans;

Offset(final int c1, final int c2, final boolean trans) {
this.c1 = c1;
this.c2 = c2;
this.trans = trans;
}
}

if (s1 == null || s1.isEmpty()) {
if (s2 == null) {
return 0;
}

if (s1.isEmpty()) {
return s2.length();
}

if (s2 == null || s2.isEmpty()) {
if (s2.isEmpty()) {
return s1.length();
}

Expand Down