我一直在想着这个事,早晨起来五六点,躺在床上冥想。突然悟解了,真如某些书上写的,大道不过三言两语,说破一文不值。
还是按照老方法,把问题最大程度的精简,现在求集合A={a,b}的幂集,只有两个元素,应该有{a,b},{a},{b},{x}四种可能。如果把这两个元素弄清楚了,其余的也都一样, 仅仅是数量增大了一些。
现在用两个数组,A是原集,B存放子集。关键是约束条件,就是边界如何界定。先这样考虑,先在B集合中放入一个元素,再放入一个元素,已经不能再放了,因为A集只有两个元素,就像是手中只有两个球,都拿出去就没有了,所以这里把约束条件定为,只要拿出去的数量>=实际数量就返回。

如图所示,这里用的是下标,所以第一次拿出a时,i=0,(以后类同),再放一个,i=1,企图再放一个i=2时已经触到边界,因为拿出去的数量已经最大。到此返回,打印结果,于是得到一个集合{a,b}。

接着,出现了转移。假如把第二个字符b收回(相当于没放),虽然没放东西,但是经过了一步,于是接着得到i=2,又触到边界,打印结果返回,结果得到集合{a}。
这就类似于树的先序遍历,如果是先序遍历的思路,剩下的就容易理解,因为先序的返回顺序是简易的,现在i=1的情况已经穷尽,也就是左右子树都已经返回,下一步就转移到根结点,也就是i=0时的情况。

同样,由于是递归,所以把a也舍去,然后遍历根的右子树,进行i=1计算。

void f(int i,char A[],int n)
{
char x;
int k;
if(i>=n)
{
if(B[])
cout<<'{'<<B<<'}'<<endl;
else
cout<<'x'<<endl;
}
else
{
x=A[i];
k=strlen(B);
B[k]=x;
f(i+,A,);
B[k]=;
f(i+,A,);
}
}

i=1的计算如下:
由于舍去a,相当于集合B没有放入一个元素,长度为0,因此,进入函数f(1)时,把A集合的第二个元素,也就是b放了B[k],也就是B[0]中。

再进入,i=2时,触到边界返回。这只是f(1)的左子树,接着进入右子树,同样,把b舍去,也即b[k]=0,(b[0]=0),进入f(2),由于集合B完全为空,所以最后打印空集'x'。

到这时,f(0)所调用的函数,左子树和右子树都已经返回,函数结束,打印的顺序为,ab,a,b,x。
这种回溯算法,初次接触会有些绕,不要用一大堆数据,把它简化成最简易的形式,递归调用步数少的演示一番,就容易看的明白。

这题的关键有两条,第一,划定边界,也就是什么条件下递归结束。第二,在递归过程中间,返回的时候需要处理什么事,也就是所谓的回溯!比如这段代码中的b[k]=0,是最关键的一步,也就是舍去某些元素!

11.字符串{a,b}的幂集[回溯递归]的更多相关文章

  1. 2553 ACM N皇后 回溯递归

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2553 中文题目,题意很简单. 思路:听说这是学习递归的经典题目,就来试试,发现自己一点想法都没有,一遇到递 ...

  2. #C++初学记录(N皇后#回溯递归)

    <font size=5 face"微软雅黑">N皇后Problem Description <font size=4 face"微软雅黑"& ...

  3. 再谈循环&迭代&回溯&递归&递推这些基本概念

    循环:不断重复进行某一运算.操作. 迭代:不断对前一旧值运算得到新值直到达到精度.一般用于得到近似目标值,反复循环同一运算式(函数),并且总是把前一 次运算结果反代会运算式进行下一次运算 递推:从初值 ...

  4. 深悉正则(pcre)最大回溯/递归限制

    对于如下的正则 /<script>.*?<\/script>/is 当要匹配的字符串长度大于100014的时候, 就不会得出正确结果: $reg = "/<sc ...

  5. hihocoder 1680 hiho字符串2 dp求方案数+递归

    我们定义第一代hiho字符串是"hiho". 第N代hiho字符串是由第N-1代hiho字符串变化得到,规则是: h -> hio i -> hi o -> ho ...

  6. Pandas | 11 字符串函数

    在本章中,我们将使用基本系列/索引来讨论字符串操作.在随后的章节中,将学习如何将这些字符串函数应用于数据帧(DataFrame). Pandas提供了一组字符串函数,可以方便地对字符串数据进行操作. ...

  7. Chinese Mahjong UVA - 11210 (暴力+回溯递归)

    思路:得到输入得到mj[]的各个牌的数量,还差最后一张牌.直接暴力枚举34张牌就可以了. 当假设得到最后一张牌,则得到了的牌看看是不是可以胡,如果可以胡的话,就假设正确.否者假设下一张牌. 关键还是如 ...

  8. 单词拼接(dfs/回溯/递归)

    单词拼接传送门 //单词拼接 #include<stdio.h> #include<string.h> #include<algorithm> using name ...

  9. c++ 11字符串与string转换常用函数

    这里主要介绍一下string to int 其他方法与这个类似,可到头文件 <string> 中查看 @_Str 转换的字符串 @_Idx 转换的长度(位数) @_Base 进制 doub ...

随机推荐

  1. UNION会自动删除重复项,union与union all的差异

    UNION会自动删除重复项,刷选出部分字段的时候要注意了,如果刷选出来的两个字段的值完全相同就会剩下一个. UNION ALL 和 UNION 不同之处在于 UNION ALL 会将左右两个查询的结果 ...

  2. Elon Musk

    人物事件 成长学习 年6月28日,埃隆·马斯克在南非的比勒陀利亚出生,他的 埃隆·马斯克 父亲是一名南非机电工程师,母亲是加拿大人,从事营养师兼模特.[8]  年,10岁的马斯克就拥有了自己的第一台电 ...

  3. maven 的聚合

  4. fiddler 发送get请求

    点击Composer 点击执行(Execute) \ 这里演示的是带cookie

  5. auto semicolon insertion 自动分号补齐的坑

    今天发现js自动分号补齐的坑,来看如下两段代码: function Hello(){ return { name: ’JavaScript’ }; } alert(Hello()); //输出unde ...

  6. express中使用ejs

    [express中使用ejs] 1.添加 ejs 依赖. npm install ejs --save 2.设置 view engine 为 ejs 即可.

  7. 二叉树的创建、遍历(递归和非递归实现)、交换左右子数、求高度(c++实现)

    要求:以左右孩子表示法实现链式方式存储的二叉树(lson—rson),以菜单方式设计并完成功能任务:建立并存储树.输出前序遍历结果.输出中序遍历结果.输出后序遍历结果.交换左右子树.统计高度,其中对于 ...

  8. 常用特殊符号的HTML代码(HTML字符实体)

    适当使用实体,对页面开发有相当大的帮助. 自己收集的一些常用的以实体代替与HTML语法相同的字符,避免浏览解析错误. 常用HTML字符实体(建议使用实体): 字符 名称 实体名 实体数 • 圆点   ...

  9. 指针c艹

    #include <iostream> using namespace std;int value=1;void func(int *p){ p=&value; }void fun ...

  10. iOS 多页面跳转同一页面时数据处理

    如果 同一个界面, 会有10个数据源传进来, 此时 创建 一个总模型fullmodel 存储 10个model 数据, 创建 10个一样的cell, 在 不同数据, 用不同cell处理最好, 千万别于 ...