将字符串与二叉搜索树中的对象进行比较
Compare string against objects in binary search tree
寻求帮助。因为我试图获取用户的输入,这是字符串。然后,比较与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++编码。 我希望我能有所帮助,尽管我指出了我看到的一些重大错误,但不仅仅是回答。如果我错过了某些内容或只是知道您在提供的代码中的意思,请随时纠正我。也请随时提问!
- 对于BTreeMap和其他依赖于Ord的东西,是否有等效于C++比较器对象?
- C++ <algorithm> 使用对象作为比较定义的 sort()
- C++,如何使用常量对象和非常量对象进行比较?
- 绘制一个对象,比较模具缓冲区的两个不同值
- 隐式转换为比较函数对象(函子)用于 std::sort 而不是 std::map?
- 访问类对象以与全局变量进行比较
- 在单元测试中,如何在不使用 operator== 的情况下比较两个对象,这可能会错过新成员?
- 为什么地图需要实现'operator<'以及如何比较对象?
- 如何使用std::lower_bound比较对象变量,而不使用第二个对象进行比较
- std::用派生类对象设置,但用gcc8.1设置基类比较器
- 尝试使用比较运算符对对象向量进行排序
- 可作为常量调用的比较对象
- 在 MSVC 中,从 std::string_view 派生的对象比较不明确
- 如何改进我的"String"对象比较功能
- 重载对象成员的比较运算符
- 如何为C++映射创建自己的字符串比较对象
- 为什么使用 and 运算符比较 if 语句中的 2 个对象会抛出错误,而使用 2 if 语句则不会
- c++:旋转锁或互斥对象比较(简单计算)
- 继承中的对象比较
- 使用自定义函数对象比较器 c++ 设置