如何处理 c++ 中类实现中的"invalid use of non-static data member"?

How to handle "invalid use of non-static data member" in class Implementation in c++?

本文关键字:use invalid of non-static member data 实现 何处理 处理 c++      更新时间:2023-10-16

我一直在试图解决LeetCode上的Word Search II问题,该问题需要使用Trie来帮助提高回溯调用的效率,并且基本上都是要使用的。我一直在尝试实现我自己的Trie类,但我在remove函数中遇到了障碍,它需要一个根的副本,但我不确定如何给它一个副本。这是我遇到麻烦的部分:

函数remove(string word, TrieNode* crawl = root, int depth = 0)中的

TrieNode* crawl = root

错误:无效使用非静态数据成员"Trie::root">

我不知道该怎么做。

TrieNode* remove(string word, TrieNode* crawl = root, int depth = 0) { 
if(!crawl) return nullptr; 
if(depth == word.size()) { 
if(crawl->isLeaf) crawl->isLeaf = false; 
if(isEmpty(crawl)) { 
delete crawl; 
crawl = nullptr; 
} 
return crawl; 
}
int index = word[depth] - 'a';            
crawl->arr[index] = remove(word, crawl->arr[index], depth + 1); 
if(isEmpty(crawl) && crawl->isLeaf == false) { 
delete crawl; 
crawl = nullptr; 
} 
return crawl; 
} 

这就是我的Trie课程的样子:

class Trie {
private:
TrieNode* root;
public:            
Trie() : root(new TrieNode()) {};

void insert(const string &word) {
auto crawl = root;
// does it's thing
}
bool search(const string &word) {
auto crawl = root;
// does it's thing
}

bool isPrefix(const string &word) {
auto crawl = root;
// does it's thing
}

bool isEmpty(TrieNode* root) { 
for(int i = 0; i < 26; i++) if(root->arr[i]) return false; 
return true; 
} 

TrieNode* remove(string word, TrieNode* crawl = root, int depth = 0) { 

以此为TrieNode:

struct TrieNode {
bool isLeaf;
vector<TrieNode*> arr;
TrieNode() : isLeaf(false), arr(26, nullptr) {};
};

编辑:特别感谢@SPD建议改进删除功能

@darune的答案的替代方案是过载:

TrieNode* remove(const string& word)
{
return remove(word, root);
}
TrieNode* remove(string word, TrieNode* crawl, int depth = 0) { 
//...

不能将成员变量用作默认参数。

但是不是:

TrieNode* remove(string word, TrieNode* crawl = root, int depth = 0) { 
//...

你可以做

TrieNode* remove(string word, TrieNode* crawl = nullptr, int depth = 0) { 
if (!crawl) {
crawl = root;
}
//...

几个建议:

  1. 您并不真正需要Trie类,TrieNode就足够了。所有插入/删除操作都可以移动到TrieNode,您可能会发现编写TrieNode的成员函数更"自然">
  2. 如果您坚持现有的设计并删除爬网本身和crawl = nullptr,我认为您需要通过指针引用而不仅仅是指针来传递爬网
  3. #2的替代方案是删除调用堆栈中的爬网。remove((现在返回一个布尔值,指示调用者是否可以安全地删除此节点。下面的示例代码
  4. 最后,请考虑使用托管ptr而不是原始ptr。(这对于leetcode练习来说可能并不重要(
bool remove(string word, TrieNode* crawl, int depth = 0) { 
if(!crawl) return true; 
if(depth == word.size()) { 
if(crawl->isLeaf) crawl->isLeaf = false; 
return isEmpty(crawl);
}
int index = word[depth] - 'a';
if (remove(word, crawl->arr[index], depth + 1)) {
// it's empty or nullptr, safe to remove
delete crawl->arr[index];
crawl->arr[index] = nullptr; 
}
return !crawl->isLeaf && isEmpty(crawl);
}