将字符串与二叉搜索树中的对象进行比较

Compare string against objects in binary search tree

本文关键字:对象 比较 搜索树 字符串      更新时间:2023-10-16

寻求帮助。因为我试图获取用户的输入,这是字符串。然后,比较与myBST中的单词变量匹配的字符串,然后打印出来。不幸的是,我的二叉搜索树包含一个名为 WordApp 的类,它由 int 频率组成;字符串单词。

我正在尝试比较与 WordApp 对象中的单词变量匹配的用户输入,但我无法直接访问它。这是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 argument 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) 将输入的字符串变量与无法识别的对象类进行比较。我试图思考,但一无所获。 任何人都可以帮忙吗?

首先我想指出这一点,因为返回类型你的函数是布尔值,所以返回 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);
}
}

我相信你注意到我添加了运算符==,这显然不是为WordApp定义的,但在你的例子中,你从来没有真正测试过你是否找到了你要找的东西。如果它大于结果,则首先对其进行测试,然后在 else 分支中不测试任何内容。要修复它,您可以实现运算符 == 并在之前对其进行测试,或者只是实现运算符

此外,我建议在标头中实现模板类(如果您不知道为什么,您应该研究一下)并且在类的声明原因中,然后它的函数是隐式内联的。如果您有兴趣,我们可以将这个问题从stackoverflow中移出,而只是研究总体上改进您的C++编码。 我希望我能有所帮助,尽管我指出了我看到的一些重大错误,但不仅仅是回答。如果我错过了某些内容或只是知道您在提供的代码中的意思,请随时纠正我。也请随时提问!