gpt4 book ai didi

c++ - 为什么我的 std::set find() 不起作用?

转载 作者:行者123 更新时间:2023-11-30 02:58:56 25 4
gpt4 key购买 nike

我有以下功能,但无法弄清楚为什么它不起作用。

参数是一组非终结符和一个 GrammarSymbol*(一个词) vector 。 Nonterminal 是 GrammarSymbol 的子类。该函数应该过滤单词中包含的所有非终结符以及非终结符集中的所有非终结符,并将它们返回到一个集合中。

std::set<Nonterminal> Filter(const std::set<Nonterminal>& symbolSet, const std::vector<GrammarSymbol*> w){

//resulting set
std::set<Nonterminal> rSet;

std::vector<GrammarSymbol*>::const_iterator wit;
std::set<Nonterminal>::const_iterator ntit;

//iterate over all symbols of the word
for(wit = w.begin(); wit != w.end(); wit++){

//test if current symbol is a nonterminal
const Nonterminal* nt = dynamic_cast<const Nonterminal*>(*wit);
if(nt != NULL){
std::cout << "current symbol " << nt->Str() << " is nonterminal" << std::endl;

for(ntit = symbolSet.begin(); ntit != symbolSet.end(); ntit++){
std::cout << ntit->Str() << " " << (!(*ntit < *nt) && !(*nt < *ntit))<< std::endl;
}
//look for the symbol in the nonterminal set
ntit = symbolSet.find(*nt);

//if the symbol was found, insert it into resulting set
if(ntit != symbolSet.end()){
rSet.insert(*ntit);
std::cout << "inserted " << ntit->Str() << "into set, size: " << rSet.size() << std::endl;
}
else{
std::cout << "not found in symbolSet" << std::endl;
}
}
}
return rSet;
}

这会产生输出

current symbol (1, 2, 2) is nonterminal
(1, 2, 2) 1
(2, 3, 3) 0
(3, 2) 0
(4, 3) 0
(5, 3, 1) 0
not found in symbolSet

如果我不依赖过滤器函数和自己的过滤器,它工作得很好:

std::set<Nonterminal> Filter(const std::set<Nonterminal>& symbolSet, const std::vector<GrammarSymbol*> w){

//resulting set
std::set<Nonterminal> rSet;

std::vector<GrammarSymbol*>::const_iterator wit;
std::set<Nonterminal>::const_iterator ntit;

//iterate over all symbols of the word
for(wit = w.begin(); wit != w.end(); wit++){

//test if current symbol is a nonterminal
const Nonterminal* nt = dynamic_cast<const Nonterminal*>(*wit);
if(nt != NULL){
std::cout << "current symbol " << nt->Str() << " is nonterminal" << std::endl;

for(ntit = symbolSet.begin(); ntit != symbolSet.end(); ntit++){
std::cout << ntit->Str() << " " << (!(*ntit < *nt) && !(*nt < *ntit))<< std::endl;
if(!(*ntit < *nt) && !(*nt < *ntit)){
rSet.insert(*ntit);
}
}
}
}
return rSet;
}

谁能给我解释一下这里发生了什么?据我所知,std::set 应该将元素与 operator< 进行比较。比较似乎工作得很好,如输出所示。

我会继续使用自制过滤器,但我担心存在更大的潜在问题。

谢谢!

编辑:非终结符和非终结符的运算符<:

class Nonterminal : public GrammarSymbol{

public:

/** The start state*/
Idx mStartState;
/** The stack symbol*/
Idx mOnStack;
/** The end state */
Idx mEndState;
//...
}

Idx 只是一个 int 的类型定义。

bool Nonterminal::operator<(const GrammarSymbol& other) const{
if(typeid(*this) != typeid(other)) return true; //other is a terminal
const Nonterminal& nt = dynamic_cast<const Nonterminal&>(other); //other is a nonterminal
if (mStartState < nt.StartState()) return true;
if (mOnStack < nt.OnStack()) return true;
if (mEndState < nt.EndState()) return true;
return false;
}

最佳答案

operator <不正确

考虑

Nonterminal nt1 (1,2,3);
Nonterminal nt2 (3,2,1);

bool b1 = nt1 < nt2;
bool b2 = nt2 < nt1;

对于 nt1 < nt2比较:

  • 1 < 3立即产生true ;

对于 nt2 < nt1 :

  • 3 < 1不成立,所以你继续
  • 2 < 2这不成立,所以你继续
  • 1 < 3持有

因此b1b2将是 true , 这是废话

关于 filter 的第二个变体, 它在逻辑错误的情况下工作

for(ntit = symbolSet.begin(); ntit != symbolSet.end(); ntit++){
std::cout << ntit->Str() << " " << (!(*ntit < *nt) && !(*nt < *ntit))<< std::endl;
if(!(*ntit < *nt) && !(*nt < *ntit)){
rSet.insert(*ntit);
}

在这里rSet.insert(*ntit);每次都会被调用if(!(*ntit < *nt) && !(*nt < *ntit))不成立,一次也不成立。

关于c++ - 为什么我的 std::set find() 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13359945/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com