分析题意
题目地址:CS106B Recursion!
题意就是说给一句话,这句话里面有n个英语单词,每个单词有可能小写也可能大写,给出所有情况组成的集合。抽象成数学语言就是一个枚举所有子集的问题,题目要求只能用递归。
例如给定句子 "what are YOU doing?"
可能的情况有
首先它提供了这个函数
Vector<string> tokenize(const string& sentence);
它将一个句子作为输入,然后返回一个Vector<string>,表示组成该句子的各个单元。
那么怎么实现呢,这里用到了递归与回溯的思想,也就是说涉及到一个"深度"的问题,"深度"是递归的次数,递归思想可以参考我以前的博客实现一个函数返回树中长度至少为n的所有路径的列表,题目选自CS61A 2021 LAB9 Q11: Long Paths_idMiFeng的博客-CSDN博客
这篇文章介绍的是树的递归与回溯,相关的思想就可以非常好的迁移到这题中。
回溯简单来说也就是一条路走完后,向老板报告(把数据存入最终要返回的res),然后往回走(删掉添加的元素)到起点后重新走另一条路,如此重复。
代码部分
bool isword(const string word)
{
if(word==" ")return false;
else if(!isalpha(word[0]))return false;
else return true;
}
void help(Set<string>& res,Vector<string>&elems,Vector<string>vector,int d){
if(d==elems.size()){
string w;
for(string s:vector)w+=s;
res+=w;
return;
}
else if(isword(elems[d])){
string tem1 = toUpperCase(elems[d]);
string tem2 = elems[d];
vector.add(tem1);
help(res,elems,vector,d+1);
//删除最后一个元素
vector.remove(vector.size()-1);
vector.add(tem2);
help(res,elems,vector,d+1);
}
//如果当前单词不是有效的单词,那么它会被直接添加到 vector 中,并继续递归处理下一个单词
else{
vector.add(elems[d]);
help(res,elems,vector,d+1);
}
}
Set<string> allEmphasesOf(const string& sentence) {
/* TODO: Delete this line and the next one, then implement this function. */
Set<string> res;
Vector<string> elems=tokenize(sentence);
for(int i=0;i<elems.size();i++)
elems[i]=toLowerCase(elems[i]);//题目要求忽略原句子的大小写
//Vector<string>vector;
help(res,elems,{},0);
return res;
}
isword
函数:它通过检查字符串是否为空格或首字符是否为字母来确定一个字符串是否是有效单词。
allEmphasesOf
函数:它的目标是生成句子的所有可能的强调形式。
help
函数:这个函数是递归的核心部分,用于生成所有可能的强调形式。它有以下参数:
res
:一个存储结果的Set<string>
,每次生成一个强调形式时,将其添加到结果中。elems
:一个包含句子中单词的Vector<string>
。vector
:一个临时的Vector<string>
,用于存储当前正在生成的强调形式。d
:表示当前处理的单词在elems
中的索引。(深度)函数开始时,它检查递归结束的条件。如果
d
等于elems.size()
,这意味着我们已经处理完了所有单词,可以将当前vector
中的内容作为一个强调形式添加到res
中。如果当前单词是一个有效的单词(通过
isword
函数检查),则会生成两种情况:
- 一种情况是将当前单词转换为大写形式,然后将其添加到
vector
中,接着递归处理下一个单词,处理完成后需要从vector
中删除最后一个添加的元素,以便回溯到上一个状态。- 另一种情况是将当前单词保持为原样,然后将其添加到
vector
中,接着递归处理下一个单词,同样需要在递归完成后从vector
中删除最后一个元素。如果当前单词不是有效的单词,那么它会被直接添加到
vector
中,并继续递归处理下一个单词。当递归完成后,
allEmphasesOf
函数返回存储在res
中的所有可能的强调形式。总之,它会在每个单词处考虑两种情况:一种是将当前单词强调,另一种是不强调,然后不断地向下递归生成所有可能的组合。这种方法确保了所有可能的情况都会被考虑到。
总结经验
该题与上文发的之前文章解析的题的相同点在于,当达到足够的深度之后,才能把结果存入最终的ans中,上文的链接一定要看看!!!