/*******************************************************************************
* Copyright (c) 2012 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.docs.intent.compare.utils;
import org.eclipse.emf.compare.utils.DiffUtil;
/**
* String distance computation utilities.
*
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
*/
public final class StringDistanceUtils {
/**
* Maximum distance between 2 strings.
*/
private static final double DEFAULT_MAX_STRING_DISTANCE = 500;
/**
* Impact of a size difference.
*/
private static final double DEFAULT_STRING_SIZE_DISTANCE_IMPACT = 0.7;
/**
* Sorensen-Dice coefficient.
*/
private static final double DEFAULT_STRING_DICE_DISTANCE_IMPACT = 0.3;
/**
* Prevents instantiation.
*/
private StringDistanceUtils() {
}
/**
* Returns the distance between two strings.
*
* @param a
* the first string
* @param b
* the second string
* @return the distance between two strings
*/
public static Double getStringDistance(String a, String b) {
return getStringDistance(a, b, DEFAULT_STRING_DICE_DISTANCE_IMPACT,
DEFAULT_STRING_SIZE_DISTANCE_IMPACT);
}
/**
* Returns the distance between two strings. Note: diceDistanceImpact + sizeDistanceImpact = 1
*
* @param a
* the first string
* @param b
* the second string
* @param diceDistanceImpact
* the impact of the diceCoefficient
* @param sizeDistanceImpact
* the impact of the size distance
* @return the distance between two strings
*/
public static Double getStringDistance(String a, String b, double diceDistanceImpact,
double sizeDistanceImpact) {
if (diceDistanceImpact + sizeDistanceImpact != 1) {
throw new AssertionError("dice and size impacts sum must be equal to 1, currently "
+ diceDistanceImpact + sizeDistanceImpact);
}
Double res = DEFAULT_MAX_STRING_DISTANCE;
if (a != null && b != null) {
double sizeCoeff = 1 - (2d * Math.abs(a.length() - b.length())) / (a.length() + b.length());
double diceCoefficient = DiffUtil.diceCoefficient(a, b);
double average = diceCoefficient * diceDistanceImpact + sizeCoeff * sizeDistanceImpact;
res = (double)((1 - average) * DEFAULT_MAX_STRING_DISTANCE);
} else if (a == null && b == null) {
res = Double.valueOf(0);
}
return res;
}
}