查找所有可能的大小为n的数组,其中包含所有可能顺序中另一个数组的所有可能元素组合?

时间:2013-11-08 20:32:48

标签: c++ c combinatorics

对于任意长度为n的数组A,我想用一个包含A元素的所有可能顺序的A的所有元素组合来填充n x m数组B.例如,如果A = {1,2,3}和m = 2,我想把B作为:

11

12

13

21

22

23

31

32

33

在C / C ++中执行此操作的有效方法是什么?谢谢!

编辑:这是我想出来的工作(数据在类梳子中,基本上是一个带有一些附加技巧的矩阵类):

void combs::setCombs (int arr[], int n, int m) {
    int z, tmp, repeat;
        int max = (int (pow(double (n), double( m ))));
        for (int i = 0; i < m; i++) {
                z = 0;
                repeat = int (pow( double (n), double (i)));
                for (int j = 0; j < repeat; j++) {
                        for (int k = 0; k < n; k ++) {
                                for (int p = 0; p < max/(n*repeat); p ++) {
                                        cout << arr[k] << endl;
                                        data[z*ROWS + i] = arr[k];
                                        z++;
                                }
                        }
                }
        }
}

3 个答案:

答案 0 :(得分:0)

#include<iostream>

using namespace std;
void printStrRec(string s,string ans,int k,int i)
{
    if(i==k)
    {
        cout<<"\nAnswer : "<<ans<<endl;
    }
    else
    {
        for(int x=0;x<s.size();++x)
        {
            ans[i]=s[x];
            printStrRec(s,ans,k,i+1);
        }
    }
}
void printStrings(string s,int k)
{
    string ans;
    for(int p=0;p<k;++p)
    {
        ans+="x";
    }
    printStrRec(s,ans,k,0);
}
int main()
{
    int k;
    string s;
    cout<<"Enter the set : ";
    cin>>s;
    cout<<"\nEnter k : ";
    cin>>k;
    printStrings(s,k);
    return 0;
}

希望有所帮助。

答案 1 :(得分:0)

正如@Joachim Pileborg所提到的那样,你的问题在参数方面缺乏很多。
但是让我们说你可以保证你传递了一个SORTED UNIQUE int的向量。那么这种蛮力是可能的:

std::vector< std::string > Combo( const std::vector< char >& source, int m )
{
    std::vector< std::vector< char >::const_iterator > digits( length, source.cbegin() );
    std::vector< std::string > result( source.size() * m );

    for( int i = 0; i < result.size(); i++ )
    { 

        for( int j = 0; j < m; j++ )
        {
            result[i] += *(digits[j]);
        }

        for( int j = digits.size() - 1; j >= 0; j-- )
        {
            ++digits[j];

            if( digits[j] == source.cend() )
            {
                digits[j] = source.cbegin();
            }
            else
            {
                break;
            }
        }
    }
    return result;
}

答案 2 :(得分:0)

您所描述的内容听起来像是部分排列,而不是组合。

如果您使用的是c ++,那么建议使用向量,因为向量可以告诉您它们的大小,并且它们可以释放自己的内存。使用向量的实现如下:

vector<vector<int> > partialPermutations(vector<int> &A,int m){
    int i,i2,t,n=A.size(),total=1;
    for(i=0;i<m;i++) total*=n;
    vector<vector<int> > result;
    for(i=0;i<total;i++){
        result.push_back(vector<int>());
        t=i;
        for(i2=0;i2<m;i2++){
            result[i].push_back(A[t%n]);
            t/=n;
        }
    }
    return result;
}

int main() {
    vector<int> A;
    int total,i,i2;
    for(i=1;i<=4;i++) A.push_back(i);
    vector<vector<int> > re=partialPermutations(A,2);
    for(i=0;i<re.size();i++){
        for(i2=0;i2<2;i2++)
            cout<<re[i][i2]<<" ";
        cout<<endl;
    }
    return 0;
}

如果您仍想使用数组,则代码如下:

int** partialPermutations(int*A,int n,int m,int &total){
    int i,i2,t;
    total=1;
    for(i=0;i<m;i++) total*=n;
    int **result=new int*[total];
    for(i=0;i<total;i++){
        t=i;
        result[i]=new int[m];
        for(i2=0;i2<m;i2++){
            result[i][i2]=A[t%n];
            t/=n;
        }
    }
    return result;
}

int main() {
    int A[]={1,2,3,4};
    int total,i,i2;
    int **re=partialPermutations(A,4,2,total);
    for(i=0;i<total;i++){
        for(i2=0;i2<2;i2++)
            cout<<re[i][i2]<<" ";
        cout<<endl;
    }
    //Cleanup
    for(i=0;i<total;i++) delete[] re[i];
    delete[] re;
    return 0;
}

请注意,通过使用数组,我们必须恢复结果数组的大小(通过引用传递total),然后我们必须释放内存。这些都不是矢量所必需的。