一句话里面有n个英语单词,每个单词有可能小写也可能大写,给出所有情况组成的集合,选自CS106B 2022Winter Assignment 3 Recursion Part Three

分析题意

题目地址: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;
}
  1. isword 函数:它通过检查字符串是否为空格或首字符是否为字母来确定一个字符串是否是有效单词。

  2. allEmphasesOf 函数:它的目标是生成句子的所有可能的强调形式。

  3. help 函数:这个函数是递归的核心部分,用于生成所有可能的强调形式。它有以下参数:

    • res:一个存储结果的 Set<string>,每次生成一个强调形式时,将其添加到结果中。
    • elems:一个包含句子中单词的 Vector<string>
    • vector:一个临时的 Vector<string>,用于存储当前正在生成的强调形式。
    • d:表示当前处理的单词在 elems 中的索引。(深度)
  4. 函数开始时,它检查递归结束的条件。如果 d 等于 elems.size(),这意味着我们已经处理完了所有单词,可以将当前 vector 中的内容作为一个强调形式添加到 res 中。

  5. 如果当前单词是一个有效的单词(通过 isword 函数检查),则会生成两种情况:

    • 一种情况是将当前单词转换为大写形式,然后将其添加到 vector 中,接着递归处理下一个单词,处理完成后需要从 vector 中删除最后一个添加的元素,以便回溯到上一个状态。
    • 另一种情况是将当前单词保持为原样,然后将其添加到 vector 中,接着递归处理下一个单词,同样需要在递归完成后从 vector 中删除最后一个元素。
  6. 如果当前单词不是有效的单词,那么它会被直接添加到 vector 中,并继续递归处理下一个单词。

  7. 当递归完成后,allEmphasesOf 函数返回存储在 res 中的所有可能的强调形式。

总之,它会在每个单词处考虑两种情况:一种是将当前单词强调,另一种是不强调,然后不断地向下递归生成所有可能的组合。这种方法确保了所有可能的情况都会被考虑到。

总结经验 

该题与上文发的之前文章解析的题的相同点在于,当达到足够的深度之后,才能把结果存入最终的ans中,上文的链接一定要看看!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

idMiFeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值