我想从“三元搜索树”库(sourceforge和http://code.google.com/p/ternary-search-tree/)中修改递归函数。默认行为是在三元搜索树中搜索与指定通配符字符串匹配的所有字符串。即如果我搜索“KE*”,在树中拥有“KEY”、“KE1”、“KE2”会找到所有条目。但我需要相反的行为 - 在三元搜索树(包含通配符)中搜索与指定字符串匹配的所有条目。即如果我搜索“KEY”,在树中有“KE*”、“KEY”、“K*”应该会找到所有条目。
树/节点定义如下:
typedef struct TstNode {
TstNode( char c ) : splitChar(c), left(0), right(0), mid(0){
}
char splitChar;
TstTree left, right;
union {
TstTree mid;
int index;
};
} tstNode;
以及具有默认行为的函数:
template <class Object>
void TernarySearchTree<Object>::partialMatchSearch(TstTree tree, const char *key)
{
if (!tree) return;
// partial match left
if (*key == '?' || *key == '*' || *key < tree->splitChar)
{
partialMatchSearch( tree->left, key );
}
// partial match middle
if (*key == '?' || *key == '*' || *key == tree->splitChar)
{
if ( tree->splitChar && *key )
{
if ( *key == '*' )
{
partialMatchSearch( tree->mid, key );
}
else
{
partialMatchSearch( tree->mid, key+1 ); // search next pattern char
}
}
}
if ( ( *key == 0 || *key == '*' ) && tree->splitChar == 0 )
{
pmVectorPtr->add( tree->index );
}
if (*key == '?' || *key == '*' || *key > tree->splitChar)
{
partialMatchSearch( tree->right, key );
}
}
pmVectorPtr 是一个指向 int 向量的指针,函数 get 以根元素和 searchkey 作为参数调用。我已经尝试过适应它,但还无法理解它。我自己的代码:
template <class Object>
void TernarySearchTree<Object>::partialMatchSearchInverted(TstTree tree, const char *key)
{
if (!tree) return;
if((tree->splitChar == '*') && ( *key != 0 )){
partialMatchSearchInverted( tree, key+1 );
}
if( *key != 0 ){
if (*key < tree->splitChar){
partialMatchSearchInverted( tree->left, key );
}
if (*key > tree->splitChar){
partialMatchSearchInverted( tree->right, key );
}
}
if ((*key == tree->splitChar) || (tree->splitChar == '*')){
if ( tree->splitChar || *key ){
partialMatchSearchInverted( tree->mid, key+1 ); // search next pattern char
}
}
if ( ( *key == 0 ) && ( tree->splitChar == 0 ) ){
pmVectorPtr->add( tree->index );
}
}
我已经广泛使用调试器对此进行了编码,据我所知,它“似乎”可以工作(即使通配符位于字符串的开头或中间)。但是,如果我在树中添加示例:“K*”和“Ke*”,它只会为“Key”找到一个解决方案(在本例中为 Ke*)。如果我从树中删除“Ke*”,它会为“Key”的搜索查询找到“K*”。我还是不明白为什么。
有什么想法吗?
附录(我的测试用例):
#include <iostream>
#include "ternarySearchTree/ternarySearchTree.h"
int main(int argc, char *argv[]){
TernarySearchTree<string> tst;
Vector< TstItem<String> > itemVector;
{
TstItem<String> item( "Ke*", "Value" );
itemVector.add( item );
}
{
TstItem<String> item( "K*", "Value" );
itemVector.add( item );
}
{
TstItem<String> item( "Ka*", "Value" );
itemVector.add( item );
}
tst.buildBalancedTree(itemVector);
Vector<int> matches = tst.partialMatchSearchInverted("Key");// will only find Ke* (wrong - it should find Ke* and K*), if I remove Ke* above it would find K* (right), if I remove that also it would find nothing (also right)
for (unsigned j=0;j<matches.count();j++)
{
std::cout<<"Matching: "<< tst.getKey( matches[j] ) <<" - "<< tst.getValue( matches[j] )->c_str()<<std::endl;
}
std::cout<<"total matches "<< matches.count()<<std::endl;
return 0;
}