所以我试图递归地构建一个向量,当我看到这个时,我开始认为我做错了。下面的代码是否会返回带有每个迭代结果的向量,或者我只是在每次迭代上创建新的向量,而这些向量实际上不会在每个递归调用上构建。如果我错了,我该如何递归地建立一个矢量...提前感谢您的建设性帮助!
std::vector<ParameterClass> recursiveParser :: parseParamList()
{
std::vector<ParameterClass> paramVector;
if (lexicator->getCurrentToken()->getTokenType() == STRING) {
paramVector.push_back(ParameterClass(*lexicator->getCurrentToken()));
lexicator->advance();
parseParamList();
} else if (lexicator->getCurrentToken()->getTokenType() == ID) {
paramVector.push_back(ParameterClass(*lexicator->getCurrentToken()));
lexicator->advance();
parseParamList();
} else {
// so as to not fail in Expression, i need to check to see that there is a
// left paren indicating that there should be an expression
if (lexicator->getCurrentToken()->getTokenType() == LEFT_PAREN) {
paramVector.push_back(ParameterClass(parseExpression()));
lexicator->advance();
parseParamList();
}
}
return paramVector;
}
答案 0 :(得分:4)
如果要以递归方式构建列表(向量等),请使用以下模式:
private:
void InternalBuild(std::vector<OutputData> & vec)
{
// Add data to vec
// Possibly call recursively InternalBuild(vec);
}
public:
std::vector<OutputData> RecursiveBuild()
{
std::vector<OutputData> vec;
InternalBuild(vec);
return vec;
}
值得注意的是,你似乎在这里滥用递归。递归意味着用于数据结构,它们的性质是递归的(树,图等)。在这种情况下,您可以递归地处理线性数据 - 为什么不简单地编写类似:
的内容while (!lexer.endOfExpression())
{
// Process token
lexer.Advance();
}
在你的情况下,如果你得到足够长的表达式,你最终会遇到堆栈溢出异常,因为你的程序将耗尽堆栈内存。如果你线性地实现这个算法,那将不会发生。
答案 1 :(得分:1)
试试这个,它会附加递归调用的结果
std::vector<ParameterClass> recursiveParser :: parseParamList()
{
std::vector<ParameterClass> paramVector;
if(lexicator->getCurrentToken()->getTokenType() == STRING)
{
paramVector.push_back(ParameterClass(*lexicator->getCurrentToken()));
lexicator->advance();
std::vector<ParameterClass> result = parseParamList();
std::copy(result.begin(), result.end(), std::back_inserter(paramVector));
}
else
if(lexicator->getCurrentToken()->getTokenType() == ID)
{
paramVector.push_back(ParameterClass(*lexicator->getCurrentToken()));
lexicator->advance();
std::vector<ParameterClass> result = parseParamList();
std::copy(result.begin(), result.end(), std::back_inserter(paramVector));
}else
{
// so as to not fail in Expression, i need to check to see that there is a left paren indicating that there should be an expression
if(lexicator->getCurrentToken()->getTokenType() == LEFT_PAREN)
{
paramVector.push_back(ParameterClass(parseExpression()));
lexicator->advance();
std::vector<ParameterClass> result = parseParamList();
std::copy(result.begin(), result.end(), std::back_inserter(paramVector));
}
}
return paramVector;
}
也请使用switch代替if-elseif-elseif
并避免重复代码
std::vector<ParameterClass> recursiveParser :: parseParamList()
{
std::vector<ParameterClass> paramVector;
switch(lexicator->getCurrentToken()->getTokenType())
{
case STRING:
paramVector.push_back(ParameterClass(*lexicator->getCurrentToken()));
break;
case ID:
paramVector.push_back(ParameterClass(*lexicator->getCurrentToken()));
break;
case LEFT_PAREN: // so as to not fail in Expression, i need to check to see that there is a left paren indicating that there should be an expression
paramVector.push_back(ParameterClass(parseExpression()));
break;
}
lexicator->advance();
std::vector<ParameterClass> result = parseParamList();
std::copy(result.begin(), result.end(), std::back_inserter(paramVector));
return paramVector;
}
但使用@ Spook的模式,因为它允许尾调用优化