我想修改'三元搜索樹'庫中的遞歸函數(sourceforge & http://code.google.com/p/ternary-search-tree/)。 默認行爲是在三進制搜索樹中搜索匹配指定通配符字符串的所有字符串匹配。 即,如果我搜索'KE *',樹中的'KEY','KE1','KE2'將會找到所有的entrys。 但我需要相反的行爲 - 在三元搜索樹(包含通配符)中搜索與指定字符串匹配的所有entrys。 即在我搜索'KEY'的情況下,樹中的'KE *','KEY','K *'應該找到所有的entrys。在三元搜索樹內搜索(不帶)通配符
樹/節點定義如下:
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的指針的一個向量和函數來獲取的調用根元素和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 *',它只會找到一個解決方案(在這種情況下,Ke *)爲'Key'。如果我從樹中刪除'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;
}
看的就像該黑客的作者(一個問題,三元搜索樹,編碼顯然c。與一些C++特性)。 – Walter
謝謝,好點!我也會嘗試聯繫作者,但我不希望與他聯繫,因爲從2007年起googlecode wiki頁面上仍然存在未解決的問題。 – Constantin