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)将输入字符串变量与无法识别的对象类进行比较。我试着想但却无处可去。 有人可以帮忙吗?
答案 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 ++编码。 我希望我帮助了一点,即使不仅仅是回答我指出了我看到的一些重大错误。如果我错过了某些内容,或者只是错误地了解您在提供的代码中的含义,请随意纠正我。随时也可以提问!