package info.ephyra.answerselection.filters;
import info.ephyra.search.Result;
import info.ephyra.util.StringUtils;
import java.util.ArrayList;
/**
* <p>The <code>DuplicateFilter</code> drops duplicate results. Results are
* considered equal if <code>StringUtils.equalsCommonNorm()</code> is true for
* the answer strings. In this case the result with the higher score is kept
* and its score is incremented by the score of the other result.</p>
*
* <p>This class extends the class <code>Filter</code>.</p>
*
* @author Nico Schlaefer
* @version 2006-06-28
*/
public class DuplicateFilter extends Filter {
/**
* Results with an answer string equal to one of these forbidden strings are
* dropped.
*/
private String[] forbidden = new String[0];
/**
* Adds forbidden answer strings.
*
* @param forbidden forbidden answers
*/
public void addForbiddenAnswers(String[] forbidden) {
this.forbidden = forbidden;
}
/**
* Filters duplicate results and increments the scores of the remaining
* results by the scores of the dropped results.
*
* @param results array of <code>Result</code> objects
* @return array of <code>Result</code> objects without duplicates
*/
public Result[] apply(Result[] results) {
// sort results by their scores in descending order
results = (new ScoreSorterFilter()).apply(results);
// drop results with forbidden answer strings
for (String as : forbidden)
for (int i = 0; i < results.length; i++) {
if (results[i] == null ||
results[i].getScore() == Float.POSITIVE_INFINITY) continue;
if (results[i].getScore() == Float.NEGATIVE_INFINITY) break;
if (StringUtils.equalsCommonNorm(as, results[i].getAnswer()))
results[i] = null;
}
// drop duplicates
for (int i = 0; i < results.length - 1; i++) {
if (results[i] == null ||
results[i].getScore() == Float.POSITIVE_INFINITY) continue;
if (results[i].getScore() == Float.NEGATIVE_INFINITY) break;
for (int j = i + 1; j < results.length; j++) {
if (results[j] == null ||
results[j].getScore() == Float.POSITIVE_INFINITY) continue;
if (results[j].getScore() == Float.NEGATIVE_INFINITY) break;
if (StringUtils.equalsCommonNorm(results[i].getAnswer(),
results[j].getAnswer())) {
// increment score of higher-scored result
results[i].incScore(results[j].getScore());
// drop lower-scored result
results[j] = null;
}
}
}
// return remaining results
ArrayList<Result> noDups = new ArrayList<Result>();
for (Result result : results)
if (result != null) noDups.add(result);
return noDups.toArray(new Result[noDups.size()]);
}
}