1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
//
// C++ Interface: complexscorecalculationstrategy
//
// Description:
//
//
// Author: Benjamin Mesing <bensmail@gmx.net>, (C) 2005
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef __NAPT_COMPLEXSCORECALCULATIONSTRATEGY_H_2005_08_06
#define __NAPT_COMPLEXSCORECALCULATIONSTRATEGY_H_2005_08_06
#include <aptsearchscorecalculationstrategy.h>
namespace NApt {
class IPackageDB;
class IPackage;
/** @brief Calculates the scores for each package.
*
* The scores will be calculated based on the search of the patterns in the
* names and descriptions of the packages.
*
* For each package, a score based on the names and one based on the description
* is calculated, each being being in [0..1]. They are combined by as a weighted
* average, where the name scores are weighted with 3, and the description scores
* with 1.
*
* The include patterns are searched in the package descriptions and the package names.
* Each type of match is assigned a score, where a Scores::DIRECT_CS_MATCH
* gives the highest score, and Scores::INNER_MATCH the lowest.
*
* For the name scores, for each include pattern the highest match type is determined and
* those values are accumulated (a no match means 0). For the description scores,
* all matches are accumulated and divided by the number of characters.
* Finally both, description and name scores, will be normalized and combined
* as described above.
*
* @author Benjamin Mesing
*/
class ComplexScoreCalculationStrategy : public AptSearchScoreCalculationStrategy
{
struct Scores
{
/** @brief Scores if the search pattern equals the package name (case sensitive).
*
* Only used in descriptions.
*/
static const float DIRECT_CS_MATCH;
/** @brief Scores if the search pattern equals the package name (case insensitive).
*
* Only used in descriptions.
*/
static const float DIRECT_MATCH;
/** @brief Scores if the search pattern matches a whole word in the package name or
* description (case sensitive).
*/
static const float WHOLE_CS_WORD;
/** @brief Scores if the search pattern matches a whole word in the package name or
* description (case insensitive).
*/
static const float WHOLE_WORD;
/** @brief Scores if the search pattern matches the borders of a word in the package
* name or description (case insensitive).
*
* Example: <br>
* Search pattern: apt<br>
* Word: <b>apt</b>itude
*/
static const float BORDER_MATCH;
/** @brief Scores if the search pattern matches inside a word.
*
* Example: <br>
* Search pattern: apt<br>
* Word: l<b>apt</b>op
*/
static const float INNER_MATCH;
};
/** @brief Holds the interface used to access the package database directly. */
IPackageDB* _pPackageDb;
public:
ComplexScoreCalculationStrategy(IPackageDB* pPackageDb);
virtual ~ComplexScoreCalculationStrategy();
/** @name IScoreCalculationStrategy interface
*
* Implementation of the IScoreCalculationStrategy interface
*/
//@{
/** @brief Calculates the scores for the handed set of packages.
*
* Old calculations will be cleared.
* @pre _includePatterns.size() != 0
* @see setIncludePatterns()
*/
virtual void calculateScore(const set<string>& packages);
//@}
float getNameScore(const IPackage& package, const QString& pattern) const;
float getDescriptionScore(const IPackage& package, const QString& pattern) const;
protected:
/** Information used to calculate the scores for a package. */
struct ScoreInformation
{
public:
ScoreInformation(const string& package)
{
_package = package;
_nameScore = 0;
_descriptionScore = 0;
}
const string& package() const { return _package; }
float getNameScore() const { return _nameScore; }
/** Accumulated matches divided by the number of characters in the description. */
float getDescriptionScore() const { return _descriptionScore; }
void clearScore();
void addNameScore(float score) { _nameScore += score; }
void addDescriptionScore(float score)
{
_descriptionScore += score;
if (_descriptionScore > _maximumDescriptionScore)
_maximumDescriptionScore = _descriptionScore;
}
static void clearMaximumDescriptionScore() { _maximumDescriptionScore = 0; }
static float getMaximumDescriptionScore() { return _maximumDescriptionScore; }
private:
string _package;
/** @brief The score calculated for the name. */
float _nameScore;
/** @brief The score calculated for the description. */
float _descriptionScore;
/** @brief Holds the maximum description scores reached. */
static float _maximumDescriptionScore;
};
/** @brief Structure to count the matches for one word in a text.
*
* Meaning of members as in Scores.
*/
struct Matches
{
int wholeWordCsMatches;
int wholeWordMatches;
int borderMatches;
int innerMatches;
Matches() :
wholeWordCsMatches(0),
wholeWordMatches(0),
borderMatches(0),
innerMatches(0)
{
}
};
/** @brief Searchs for pattern in string.
*
* @returns the result of the search as Matches structure.
*/
Matches findMatches(const QString& string, const QString& pattern) const;
/** @brief Returns the score information for the handed package.
*
* @throws NPlugin::PackageNotFoundException if no data was available for the handed package.
*/
ScoreInformation getScoreInformation(const string& package, bool cs) const;
};
}
#endif // __NAPT_COMPLEXSCORECALCULATIONSTRATEGY_H_2005_08_06
|