比较字符串与二进制搜索树中的对象

时间:2017-04-16 22:12:45

标签: c++ tree

寻求帮助。当我试图获得用户的输入时,这是字符串。然后,比较匹配myBST中的单词变量的字符串然后打印出来。不幸的是,我的二叉搜索树包含一个名为WordApp的类,它由int频率组成;字符串; 我试图比较与WordApp对象的word变量匹配的用户输入,但我没有直接访问它。这是WordApp的定义。

class WordApp{
int frequency;
string word;

string processText(string &);
public:
void setWord(string);
void setFrequency(int);

string getWord();
int getFrequency();

void scanText();

WordApp();

bool operator>(WordApp);
friend ostream& operator <<(ostream& out, WordApp result) //To overload "<<" cout operator in order to use .inOrderPrint()
{
    out << "(" << result.word << ", " << result.frequency << ")" << endl;
    return out;
}
bool WordApp::operator>(WordApp result) //To overload ">" greater than        operator that used in BST class, insert()
{
if (this->frequency > result.getFrequency())
{
    return 1;
}
else if (this->frequency == result.getFrequency())
{
    if (this->word.compare(result.word) > 0)
    {
        return 1;
    }
}
return 0;}

在我的二叉搜索树中,我已声明如下,以存储WordApp对象

WordApp myWord;
BST<WordApp> myBST;
myBST.insert(myWord);
string input;
cout << "Query: ";
cin >> input;
cout << myBST.Traversal(input) << endl; //search function doesn't take string as arguement since myBST<WordApp> but not myBST<string>

下面是我在二叉搜索树中实现的遍历功能

template<class T>
bool BST<T>::Traversal(T result)
{
if (root == NULL)
{
    return 0;
}

Traversal2(root, result);
return 1;
}

template<class T>
bool BST<T>::Traversal2(BTNode<T> *cursor, T result)
{
if (cursor == NULL)
{
    return;
}
if (cursor->item > result)
{
    Traversal2(cursor->left, result);
}
else
{
    Traversal2(cursor->right, result);
}
return cursor->item;
}

语句myBST.search(input)将输入字符串变量与无法识别的对象类进行比较。我试着想但却无处可去。 有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

首先我要指出这一点,因为你的函数的返回类型是bool,返回true / false而不是1/0会更清楚。

其次你的问题是遍历功能,对吧?在你提供的代码中,它返回bool(这是为了表明值是否存在?),但稍后你提到,或者至少我假设,你想要返回实际值(如果它存在)。最好的选择是返回指针(如果树中没有项目,则返回nullptr)。让我们看一下遍历函数的声明:

// now it returns pointer instead of bool
// added const& to argument type cause cause it suits this example better
// return type is T*, suits example the best
template<class T>
T* BST<T>::traversal(const T& result); 

我确信现在一切都很清楚。您的示例中存在第一个问题: 您的BST树由WordApp模板化,因此您可以在代码中查看上述函数:

template<>
WordApp* BST<WordApp>::traversal(const WordApp& result);

这真的不行,可以吗?您期望类型为WordApp,但您在main的示例中传递了std :: string。您尚未定义可以处理它的字符串或ctor的转换。如果您定义了将字符串作为参数的ctor,它应该可以工作:

template <typename T>
class WordApp {
    int frequency = 0;
    std::string word;
    // ...
public:
    WordApp() noexcept = default;
    WordApp(const std::string& w) // < this is new
        : word(w) {}
    // ...
}

让我们继续讨论遍历函数的实际算法。二叉树是非常好的结构,可以很好地利用递归。你没有真正展示BTNode类,所以我认为它看起来像这样:

template <typename T>
struct BTNode {
    T item;
    std::unique_ptr<BTNode> left;
    std::unique_ptr<BTNode> right;
    // maybe some other functions
}

template <typename T>
class BST {
    std::unique_ptr<BTNode<T>> root;
public:
    // ...
}

你的问题可能是,这个std::unique_ptr课程是什么?答案在提供的链接中。 TL; DR:它管理原始指针,并在调用std :: unique_ptr的析构函数时自动删除它。非常有用的东西,看看它。请注意,仅当您使用c ++ 11或更高版本的标准进行编译时,它才可用。

然而,让我们继续前进。我在谈论递归,所以我添加了从上面的遍历函数调用的函数:

template<class T>
T* BST<T>::traversal(const T& result) {
    return _traversal(root.get(), result);
}

template<class T>
T* BST<T>::_traversal(BTNode<T>* ptr, const T& result) {
    if (!ptr)
        return nullptr;
    // you need to test this! otherwise you just traverse to the Tree leaves without finding anything
    if (ptr->item == result) 
        return &ptr->item;
    if (ptr->item > result) {
        return _traversal(ptr->left.get(), result);
    } else {
        return _traversal(ptr->right.get(), result);
    }
}

我确定你注意到我添加了operator ==这显然没有为WordApp定义,但在你的例子中,如果你找到了你想要的东西,你从未真正测试过。如果它大于结果,你首先测试它,然后在else分支中没有测试任何东西。修复它你要么实现operator ==并在之前测试它,要么只实现operator&lt;并在其他分支中测试它。

另外我建议在头文件中实现模板类(如果你不知道为什么,你应该查看),并且在类'声明原因中,它的函数是隐式内联的。如果您感兴趣我们可以将这个问题从stackoverflow中移除,并且只是考虑改进您的C ++编码。 我希望我帮助了一点,即使不仅仅是回答我指出了我看到的一些重大错误。如果我错过了某些内容,或者只是错误地了解您在提供的代码中的含义,请随意纠正我。随时也可以提问!