package com.knowledgebooks.nlp.util; import java.util.ArrayList; import java.util.List; /** * Copyright Mark Watson 2008-2010. All Rights Reserved. * License: LGPL version 3 (http://www.gnu.org/licenses/lgpl-3.0.txt) */ public class ScoredList { private List<String> strings = new ArrayList<String>(); private List<Integer> scores = new ArrayList<Integer>(); private int max_to_keep = 9999999; public ScoredList(int max_to_keep) { this.max_to_keep = max_to_keep; } /** * Create an empty scored list */ public ScoredList() { } /** * Add a value to a scored list * * @param text * @param score * @return true is a value was added. If the score is lower than * all currently stored values and the maximum number of values to store has * been reached, then the value will not be stored and the return value will be false. */ public boolean addValue(String text, int score) { strings.add(text); scores.add(score); return removeOne(text); } /** * Add a value to a scored list. The "score" is not specified so * the "score" for a given value string is the number of times that it is added * to the scored list. * * @param text * @return true is a value was added. If the score is lower than * all currently stored values and the maximum number of values to store has * been reached, then the value will not be stored and the return value will be false. */ public boolean addValue(String text) { int score = 1; if (strings.contains(text)) { int index = strings.indexOf(text); try { score = ((Integer) scores.get(index)).intValue() + 1; } catch (Exception ignore) { ignore.printStackTrace(); } scores.set(index, new Integer(score)); } else { strings.add(text); scores.add(new Integer(score)); } return removeOne(text); } /** * Determine if a scored list contains a value string * * @param s * @return true if the value is stored in the scored list */ public boolean contains(String s) { return strings.contains(s); } private final boolean removeOne(String text) { // WARNING: REALLY INEFFICIENT !! TBD fix this int size = scores.size(); if (size > max_to_keep) { int min_val = 999999999; int min_index = 0; for (int i = 0; i < size; i++) { if (((Integer) scores.get(i)).intValue() < min_val) { min_val = ((Integer) scores.get(i)).intValue(); min_index = i; } } boolean ret = text.equals(strings.get(min_index)) == false; strings.remove(min_index); scores.remove(min_index); return ret; } else { return true; // yes, the 'text/ item was added } } /** * Sort a scored list in highest value first order */ public void sort() { for (int i = 0, size = strings.size(); i < (size - 1); i++) { for (int j = i + 1; j < size; j++) { int score_i = ((Integer) scores.get(i)).intValue(); // must be inside inner loop because of possible shuffle int score_j = ((Integer) scores.get(j)).intValue(); if (score_j > score_i) { scores.set(i, new Integer(score_j)); scores.set(j, new Integer(score_i)); String o = strings.get(i); strings.set(i, strings.get(j)); strings.set(j, o); } } } } /** * Determining the number of values in a scored list * * @return the size of the scored list */ public int size() { return strings.size(); } /** * Get a specific value * * @param index * @return the value at the specified index */ public String getValue(int index) { return (String) strings.get(index); } /** * Get a specific score * * @param index * @return the score at the specified index */ public int getScore(int index) { return ((Integer) scores.get(index)).intValue(); } /** * Get all values and scores as a human readable string * * @return string */ public String getValuesAsString() { return getValuesAsString(99999); } /** * Get a specified number of values as a human readable string * * @param max_return_values * @return string */ public String getValuesAsString(int max_return_values) { StringBuffer sb = new StringBuffer(200); sort(); int limit = strings.size(); if (limit > max_return_values) limit = max_return_values; for (int i = 0; i < limit; i++) { sb.append(strings.get(i) + ":" + scores.get(i)); if (i != (limit - 1)) sb.append(", "); } return sb.toString(); } public List<String> getStrings() { return strings; } public List<Integer> getScores() { return scores; } }