Power Set~Recursion~Hasse Diagrams

时间:2013-06-04 23:33:05

标签: c++ recursion binary

(另见以下)

所以我有一些函数和一些操作符用于编码的集合操作程序,我想将电源设置作为一个实用程序(更别关注代码中的注释)。我不想使用二进制方法,但我想使用递归。我在Ralph Oberste-Vorth的书中看到了桥梁到抽象数学电力集的定义(第65页),在下一页我看到所有这些等价,如"如果S = X,则P(S)= P(X),"和"如果A和B是集合,则P(A)U P(B)= P(A U B),"而且我想起了递归。我认为递归可以在这里工作,但我不确定。我正在玩Mathematica的Combinatorica软件包,以及Hasse Diagrams上的一个Haverford College paper,我想我可以锻炼,就像在{4}}进行四分钟一样,某种基于相应图表的方法对于某些大小为n的集合,但我不知道这将导致我正确的方式。我想建立我已经建立的函数/运算符。

#include <iostream>
#include <set>
#include <ostream>
#include <istream>
#include <vector>

using namespace std;

set<int> SetUnion( set<int> A , set<int> B ) // tus koj hlub
{
    //A.insert( B.begin() , B.end() );
    //return A;

    set<int> pump;
    for( set<int>::iterator cycle = A.begin() ; cycle != A.end() ; ++cycle )
    {
        pump.insert(*cycle);
    }
    for( set<int>::iterator cycle = B.begin() ; cycle != B.end() ; ++cycle )
    {
        pump.insert(*cycle);
    }
    return pump;
}

set<int> SetIntersection( set<int> A , set<int> B ) // tus koj hlub
{
    set<int> pump;
    for( set<int>::iterator cycle = A.begin ; cycle != A.end() ; ++cycle )
    {
        if( B.find(*cycle) != B.end() )
        {
            pump.insert(*cycle);
        }
    }
    return pump;
}

set<int> SetDifference( set<int> A , set<int> B )
{
    set<int> pump;
    for( set<int>::iterator cycle = A.begin ; cycle != A.end() ; ++cycle )
    {
        if( B.find(*cycle) == B.end() )
        {
            pump.insert(*cycle);
        }
    }
    return pump;
}

set<int> SymmetricDifference( set<int> A , set<int> B )
{
    return SetUnion( SetDifference( A , B ) , SetDifference( B , A ) );
    //return SetDifference( SetUnion( A , B ) , SetIntersection( A , B ) );
}

set<set<int>> PowerSet( set<int> A )
{
    /*statements*/
}

set<int> Complement( set<int> A , int B )
{
    set<int> pump;
    for( int i = 1 ; i<=B ; i++ )
    {
        pump.insert(i);
    }
    set<int> collect = SetDifference( A , pump );
    return collect;
}

set<int> operator+(set<int> A , set<int> B)
{
    return SetUnion( A, B );
}
set<int> operator+(set<int> A , int B)
{
    set<int> C;
    C.insert(B);
    return SetUnion( A , C );
}
set<int> operator+(int A , set<int> B)
{
    set<int> C;
    C.insert(A);
    return SetUnion( B , C );
}
set<int> operator-(set<int> A , set<int> B)
{
    set<int> pump;
    for( set<int>::iterator cycle = A.begin ; cycle != A.end() ; ++cycle )
    {
        if( B.find(*cycle) == B.end() )
        {
            pump.insert(*cycle);
        }
    }
    return pump;
}
set<int> operator-(set<int> A , int B)
{
    set<int> C;
    C.insert(B);
    set<int> pump = SetDifference( A , C );
    return C;
}
set<int> operator-(int A , set<int> B)
{
    set<int> C;
    C.insert(A);
    set<int> pump = SetDifference( B , C );
    return pump;
}
set<int> operator^(set<int> A , set<int> B)
{
    return SetUnion( A , B );
}
set<int> operator^(set<int> A , int B)
{
    set<int> C;
    C.insert(B);
    set<int> pump = SetUnion( A , C );
    return pump;
}
set<int> operator^(int A , set<int> B)
{
    set<int> C;
    C.insert(A);
    set<int> pump = SetUnion( B , C );
    return pump;
}
set<int> operator%(set<int> A , set<int> B)
{
    return SymmetricDifference( A , B );
}
set<int> operator%(set<int> A , int B)
{
    set<int> C;
    C.insert(B);
    set<int> pump = SymmetricDifference( A , C );
    return pump;
}
set<int> operator%(int A , set<int> B)
{
    set<int> C;
    C.insert(A);
    set<int> pump = SymmetricDifference( B , C );
    return pump;
}
set<int> operator~(set<int> A)
{
    set<int> pump;
    vector<int> hose;
    for( set<int>::iterator cycle = A.begin() ; cycle != A.end() ; ++cycle )
    {
        hose.push_back(*cycle);
    }
    int last_value = 
}

ostream& operator<<(ostream& out , set<int>& B) // tus koj hlub
{
    int count=0;
    if( B.size() == 0 )
    {
        out << "{}";
        return out;
    }
    else
    {
        set<int>::iterator it;
        out << "{";
        for( it = B.begin() ; it != B.end() ; ++it )
        {
            ++count;
            if( count == B.size() )
            {
                out << *it;
            }
            else
            {
                out << *it << ", ";
            }
        }
        out << "}";
        return out;
    }
}

istream& operator>>(istream& in , set<int>& B) // tus koj hlub
{
    int user_input;
    while(1)
    {
        in>>user_input;
        if(user_input == -1)
            break;
        B.insert(user_input);
    }
    return in;
}

另外,为什么我的&#34;&lt;&lt;&#34;函数中的运算符符号:

ostream& operator<<(ostream& out , set<set<int>>& B)
{
    int count=0;
    if( B.size() == 0 )
    {
        out << "{}";
        return out;
    }
    else
    {
        set<set<int>>::iterator it;
        out << "{";
        for( it = B.begin() ; it != B.end() ; ++it )
        {
            count++;
            if( count == B.size() )
            {
                out << *it;
            }
            else
            {
                out << *it << ", ";
            }
        }
        out << "}";
        return out;
    }
}

Shields先生给出的答案产生了以下错误。我试图弄清楚它为什么不起作用:

  

错误:class&#34; std :: _ Tree_const_iterator,std :: allocator&gt;&gt;&gt;&gt; &#34;没有会员&#34;插入&#34;


作者答:

set<set<int>> PowerSet( const set<int> A )
{
    set<set<int>> ps;

    if( A.size() == 0 )
    {
        ps.insert( set<int>() );

        return ps;
    }

    set<int>::iterator it = A.begin();

    int n = *it;

    set<int> s1 = A;

    s1.erase( n );

    set<set<int>> ps1 = PowerSet( s1 );

    set<set<int>> ps2;

    for( set<set<int>>::iterator it = ps1.begin() ; it != ps1.end() ; ++it )
    {
        set<int> ss = *it;

        ss.insert( n );

        ps2.insert (ss );
    }

    for( set<set<int>>::iterator it = ps1.begin() ; it != ps1.end() ; ++it )
    {
        ps.insert(*it);
    }

    for( set<set<int>>::iterator it = ps2.begin() ; it != ps2.end() ; ++it )
    {
        ps.insert( *it );
    }

    return ps;
}

1 个答案:

答案 0 :(得分:0)

下面这个C ++代码可怕低效,但我认为它应该让你知道如何递归地执行此操作。递归规则基本上是这样的:

  • P({}) = {{}}
    • 空集的功率集是包含空集
    • 的集合
  • P({n} U S) = { {n} U T | T in P(S) } U P(S)
    • {n} U S的幂集中的每一个集合都包含n或不包含n - S <幂集中每个集合中的每个集合中只有一个<{1}} / LI>

请注意,一组基数K具有基数2^K的幂集。所以你不想在任何大型集合上执行此操作!


set<set<int>> PowerSet( set<int> A )
{
    set<set<int>> PA;
    if (A.empty())
    {
        //case: P({}) = {{}}

        PA.insert(A);
    }
    else
    {
        //case: P({n} U S) = { {n} U T | T in P(S) } U P(S)

        int n = *A.begin();
        A.erase(A.begin());

        //A is now "S" from the explanation above this code

        auto PS = PowerSet(A);
        for (auto T = PS.begin(); T != PS.end(); ++T)
        {
            //add each set T from P(S)
            PA.insert(*T);

            //add each set T from P(S) with n included as well
            T->insert(n);
            PA.insert(*T);
        }
    }
    return PA;
}