| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2019 人关注过本帖
标题:一道简单的题,估计是思路有问题
只看楼主 加入收藏
fjwddzzc123
Rank: 2
等 级:论坛游民
帖 子:56
专家分:79
注 册:2009-5-7
收藏
得分:0 
回复 20楼 mfkblue
有赋值  当d=0时 i=0    x[d]=i也就是 x[0]=0   后面 d=1时     x[d-1]也就是  x[0]   都有被赋值
2009-07-24 16:34
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
leeco的代码从四点多一直用debug一步步看到现在,还是改了下,把 i=(d?x[d-1]+1:0);这句拆了放在for循环的上面,不然每次进for循环时都头晕。基本明白了程序怎么走的,但可以肯定的是,这个距离差太远了,看的心情一步步走底啊。x[]里面的值走的太厉害了。背下他的代码是没问题,想到这个思路就不太可能了
2009-07-24 17:45
fjwddzzc123
Rank: 2
等 级:论坛游民
帖 子:56
专家分:79
注 册:2009-5-7
收藏
得分:0 
...debug  是什么我还不知道    差距啊  心情一步步走到底啊
2009-07-24 19:08
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
回复 19楼 莫云今次
简单的回溯
递归里面还要调用两次,想跟着走一遍都难,调用五次以后就找不清楚返回到哪一步了。
2009-07-24 22:16
黯然神伤
Rank: 2
等 级:论坛游民
帖 子:18
专家分:39
注 册:2009-2-5
收藏
得分:0 
我也得好好学学~~~编程无极限啊
2009-07-24 22:23
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
回复 24楼 mfkblue
感觉像这种递归的不能全靠跟走,那样了解算法运行的过程可能还行,但想自己写出来就难了。比如简单的Fib数列都很难知道它是怎么递归算的,但并不一定非得知道是怎么算的才能写出来。
主要是想原理。比如你说莫云姐写的那个可以这么想:
对于第i个元素,所有的子集能分成两类,一类是包括这个元素的,一类是不包括的。
比如{abc}这个集合,对于a它的子集可以分成这两类:
{a}     {}
{ab}    {b}
{ac}    {c}
{abc}   {bc}
这8个。而且这么分不重不漏(幂集定理 其实就是这么证的~)
于是这个问题可以化简为找出{bc}的所有子集。
它的所有子集其实就是右边那列,如果可以找的出,{abc}的所有子集就是{bc}的全部子集,加上每个都加一个a的。

按这个思路就可以把求一个n元集的幂集转化为求一个n-1元集的幂集。空集只有空集这一个子集(空集定理)。所以就可能递归了~

呵呵,大概说说,我也是看她的代码想的,不代表她本人的想法~
2009-07-24 23:09
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
回复 24楼 mfkblue
我说说我的那个想法,其实这几个里,我那个可能是最容易理解的(我觉得)。

看看你给的例子,就知道求子集可以按照子集的基数找。先找出空集,基数为0。然后再找单元集,再找找双元集,三元集……

于是,要编一个辅助函数,找一个n元集的k元子集。当然考虑到这个函数比较有用(因为有时候可能需要一个k元子集,所有把这个功能单拿出来还是有一定意义的~)

然后就得看这样的子集怎么找了。观察一下规律:
如果我是12345这个集合,找三元子集,怎么找?最有规律的写法可能是像以下这样:
123
124
125
134
135
145
234
235
245
345
一共10个,肯定找齐了。如果把它们看成数的话是不是由小到大的?这样就不会重不会漏了。有点像数位间不许重复的5进制一样~
编一个函数,根据n和k,能把符合这样规律的数找出来就行了。在我那里是 __inc 这个函数。由于只是辅助功能,用双下划线开的头,其实这不是好习惯,而且取inc这个名字也很不妥当(increse,简称inc),很可能与保留的某个函数重名。呵呵
2009-07-24 23:21
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
回复 27楼 pangding
其实我一开始也想用递归的,方法可能和莫云姐那个很像。不过想了一下,就换方法了,因为感觉后来写的那个好一点(输出也好控制,效率可能也高一点)。

不过当时要是能想到Le同学的递归方法,我可能就不优化了,感觉已经很方便了。而且效率不低。
2009-07-24 23:27
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
回复 26楼 pangding
你说到abc,就是找出bc所以的子集,再加a,就abc所有的子集,这个道理就是我现在看的书上讲的一样了,道理是明白了,写起来就糊涂了.
fib那个里虽然也调用两次,但是因为按照公式写的,倒是很快写出来了。
你写的这道题的代码我还没认真看,今天就看他们那两个人代码去了。结论是跟昨天没看差不多,云山雾绕,稀里糊涂.
我没考虑不用递归的办法,但我估计应该是能写出来的,不太确定
2009-07-24 23:53
leeco
Rank: 4
等 级:贵宾
威 望:10
帖 子:1029
专家分:177
注 册:2007-5-10
收藏
得分:0 
回复 29楼 mfkblue
我写了一个更飘逸的和你题目里给的输出顺序一样的代码
程序代码:
#include <iostream>
#include <queue>
using namespace std;

char a[]="abc";
const int n=sizeof(a)-1;

void Out(int data)
{
    putchar('{');
    for(int i=0;i<n;i++)
    {
        if(data&(1<<(n-1-i)))
        {
            putchar(a[i]);
        }
    }
    putchar('}');
    putchar('\n');
}

void bfs()
{
    queue<int> Q;
    Q.push(1<<n);
    while(!Q.empty())
    {
        int t = Q.front();
        Q.pop();
        Out(t);
        for(int i=((t&(-t))>>1); i; i>>=1)
        {
            Q.push(t | i);
        }
    }
}

int main()
{
    bfs();
}
2009-07-26 16:18
快速回复:一道简单的题,估计是思路有问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029719 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved