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:
parent
9b875ca7f3
commit
d18b89bceb
@ -19,6 +19,7 @@
|
|||||||
#include "standard.h"
|
#include "standard.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using boost::algorithm::istarts_with;
|
using boost::algorithm::istarts_with;
|
||||||
|
|
||||||
@ -28,19 +29,42 @@ namespace YouCompleteMe
|
|||||||
namespace
|
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,
|
int NumWordBoundaryCharMatches( const std::string &query,
|
||||||
const std::string &word_boundary_chars )
|
const std::string &word_boundary_chars )
|
||||||
{
|
{
|
||||||
uint i = 0;
|
return LongestCommonSubsequenceLength(query, word_boundary_chars);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
@ -128,6 +128,12 @@ TEST( CompleterTest, RatioUtilizationTieBreak )
|
|||||||
ElementsAre( "aFooBarQux",
|
ElementsAre( "aFooBarQux",
|
||||||
"afbq" ) );
|
"afbq" ) );
|
||||||
|
|
||||||
|
EXPECT_THAT( Completer( Candidates(
|
||||||
|
"acaaCaaFooGxx",
|
||||||
|
"aCaafoog" ) ).CandidatesForQuery( "caafoo" ),
|
||||||
|
ElementsAre( "acaaCaaFooGxx",
|
||||||
|
"aCaafoog" ) );
|
||||||
|
|
||||||
EXPECT_THAT( Completer( Candidates(
|
EXPECT_THAT( Completer( Candidates(
|
||||||
"FooBarQux",
|
"FooBarQux",
|
||||||
"FooBarQuxZaa" ) ).CandidatesForQuery( "fbq" ),
|
"FooBarQuxZaa" ) ).CandidatesForQuery( "fbq" ),
|
||||||
|
Loading…
Reference in New Issue
Block a user