Fixed another bug in the word boundary condition

The problem was that should have been using a longest common subsequence
algorithm for the "number of word boundary character matches" calculation. Our
old approach would fail for the following case:

Query: "caafoo"

Candidate1 : "acaaCaaFooGxx"
Candidate2 : "aCaafoog"

Candidate1 needs to win. This is now also a test case.
This commit is contained in:
Strahinja Val Markovic 2012-06-24 17:58:20 -07:00
parent 9b875ca7f3
commit d18b89bceb
2 changed files with 40 additions and 10 deletions

View File

@ -19,6 +19,7 @@
#include "standard.h"
#include "Utils.h"
#include <boost/algorithm/string.hpp>
#include <algorithm>
using boost::algorithm::istarts_with;
@ -28,19 +29,42 @@ namespace YouCompleteMe
namespace
{
template< class T >
int LongestCommonSubsequenceLength(const T &first, const T &second)
{
const T &longer = first.size() > second.size() ? first : second;
const T &shorter = first.size() > second.size() ? second : first;
int longer_len = longer.size();
int shorter_len = shorter.size();
std::vector<int> previous( shorter_len + 1, 0 );
std::vector<int> current( shorter_len + 1, 0 );
for (int i = 0; i < longer_len; ++i )
{
for (int j = 0; j < shorter_len; ++j )
{
if ( longer[ i ] == shorter[ j ] )
current[ j + 1 ] = previous[ j ] + 1;
else
current[ j + 1 ] = std::max( current[ j ], previous[ j + 1 ] );
}
for (int j = 0; j < shorter_len; ++j )
{
previous[ j + 1 ] = current[ j + 1 ];
}
}
return current[ shorter_len ];
}
int NumWordBoundaryCharMatches( const std::string &query,
const std::string &word_boundary_chars )
{
uint i = 0;
uint j = 0;
while ( j < query.size() && i < word_boundary_chars.size() )
{
if ( toupper( query[ j ] ) == toupper( word_boundary_chars[ i ] ) )
++j;
++i;
}
return j;
return LongestCommonSubsequenceLength(query, word_boundary_chars);
}
} // unnamed namespace

View File

@ -128,6 +128,12 @@ TEST( CompleterTest, RatioUtilizationTieBreak )
ElementsAre( "aFooBarQux",
"afbq" ) );
EXPECT_THAT( Completer( Candidates(
"acaaCaaFooGxx",
"aCaafoog" ) ).CandidatesForQuery( "caafoo" ),
ElementsAre( "acaaCaaFooGxx",
"aCaafoog" ) );
EXPECT_THAT( Completer( Candidates(
"FooBarQux",
"FooBarQuxZaa" ) ).CandidatesForQuery( "fbq" ),