在C ++中获取数字的所有组合

时间:2012-04-25 12:28:26

标签: c++ algorithm

我需要获取给定集合的所有可能组合。例如,给定:[1,4,7],得到的组合应为:

  • 111,114,117,141,144,147,171,174,177,411,414,417,441,444,447,471,474,477,711,714,717,741,744,747 ,771,774,777。

我尝试使用next_permutation方法,但这不是我想要的(这不会返回111,144,717等值)。

那么我有什么方法可以在C ++中做到这一点?请注意,我是一个完全的初学者。

提前致谢。

7 个答案:

答案 0 :(得分:6)

仔细查看数字:您列出的所有数字也可以表示为列表{11,14,17,41,44,47,71,74,77}以1为前缀,一次为4和一次与7.这指向一般规则:

  

具有3个数字集合{1,4,7}的字符串是通过将字符串与2个相同集合的数字相加并在该集合的每个元素前面构建的。

在此规则中概括3和2,使用递归实现结果的想法,并且您有一个算法来解决您的问题。

作为C ++实现说明,请确保使用字符串而不是整数来表示您的数字。这个问题不算算,而是与base-10表示紧密耦合。字符串将使您的生活更轻松。

答案 1 :(得分:1)

创建一个包含值的数组,例如{1,4,7}。

对循环使用length(array),每个循环都有长度(数组)迭代。

在最内循环输出100 * array [i] + 10 * array [j] + array [k]


如果未知最大长度,则使用递归代替,例如的伪代码

void Solve(int[] array, int length, int position, int sum)
{
    position++;
    sum *= 10;

    for (int cnt = 0; cnt < length; cnt++)
    {
        int tempsum = sum + array[cnt];

        if (position == length)
            output(tempsum);
        else
            Solve(array, length, position, tempsum);
    }
}

答案 2 :(得分:1)

创建一个整数向量(称为vector),其大小等于集合中元素的数量。将每个条目初始化为0.然后遵循以下算法:

1)走vector,输出相应的元素。 (因此,如果向量是0,1,1并且集合是[9,8,7],则输出988 - 第0个元素,第一个元素,第一个元素。)

2)将名为element的整数设置为0。

3)增加vector[element]。检查vector[element]是否等于集合中的元素数量。如果没有,请转到第1步。

4)将vector[element]设置为零。增加element。如果element小于集合中的元素数量,请转到步骤3。

5)停止。你完成了。

答案 3 :(得分:0)

在这里查看我的答案:PHP take all combinations

提示:这不是C ++代码,但你会明白这一点。 (我建议使用递归)

答案 4 :(得分:0)

我冒昧地尝试执行任务。我想稍微提高我的算法知识。事实证明是这样的:

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;

vector<int> allowedNumbers;

bool my_next_perm(vector<int>::iterator& begin, vector<int>::iterator& end) {
    for (vector<int>::iterator itr = end - 1; ; --itr)
    {
        if (*itr != allowedNumbers.back())
        {
            *itr = *upper_bound(allowedNumbers.begin(), allowedNumbers.end(), *itr);
            while ((++itr) != end) {
                *itr = allowedNumbers[0];
            }
            return true;
        }
        if (itr == begin)
        {
            return false;
        }
    }
}
void printAllPermutationsWithRepetitions(vector<int>& v)
{
    int n = v.size();
    set<int> allNumbers;
    for (int i = 0; i < n; i++)
    {
        allNumbers.insert(v[i]);
    }
    for (set<int>::iterator itr = allNumbers.begin(); itr != allNumbers.end(); ++itr) {
        allowedNumbers.push_back(*itr);
    }
    for (int i = 0; i < n; i++) {
        v[i] = allowedNumbers[0];
    }

    do {
        for (int i = 0; i < n; i++) {
            if (i != 0) cout << " ";
            cout << v[i];
        }
        cout << endl;
    } while(my_next_perm(v.begin(), v.end()));
}

int main (int argc, char *argv[]) {
    vector<int> v;
    v.push_back(7);
    v.push_back(1);
    v.push_back(3);
    printAllPermutationsWithRepetitions(v);
    return 0;
}

实现稍微不够理想(因为我使用upper_bound)。

答案 5 :(得分:0)

你实际上用3到000的基数进行计数,用这些数字作为索引来查找[1,4,7]的数组。推广使用任意大小的输入数组:

int n = digits.size();
int n_n = std::pow(n, n);
for (int i = 0; i < n_n; ++i)
{
     int x = i;
     for (int j = 0; j < n; ++j)
     {
          cout << digits[x % n];
          x /= n;
     }
     cout << ' ';
}

答案 6 :(得分:0)

这是最简单的方法。您可以使用任意数字作为用户的输入,例如147,它会打印所有排列: 111,114,117,141,144,147,171,174,177,411,414,417,441,444,447,471,474,477,711,714,717,741,744,747,771, 774,777。

#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;

 bool Search(int A[],int num,int length)
    {
        for(int i = 0;i<length;i++)
            if(A[i] == num)
                return 1;
        return 0;
    }


    int main()
    {
        int n;
        cout << "Please Enter a Number\n";
        cin>>n;
        int num = n, k = 1;
        int count = 0;
        while(num>0)
        {
            num/=10;
            count++;
        }
        cout<<"The All Permutations of " <<n<<" are: "<<endl;
        num = n;
        int *A = new int[count];

        for(int i = 0;i<count;i++)
        {
            A[i] =  num%10;
            num/=10;
        }


        int fact = pow(count,count);
        int *Ar = new int[fact];
        int *B = new int[count];
        int value,number = 0;

        for(int i = 0;i<fact;)
        {

            for(int j = 0;j<count;++j)
            {
                value = (rand()%count);

                B[j] = value;
            }

            for(int k= 0;k<count;k++)
                number = number + A[B[k]]*pow(10,k);

            if(Search(Ar,number,fact) == 0)
            {
                cout<<k++<<". "<<number<<endl;
                Ar[i] = number;
                ++i;
            }
            number = 0;

        }

        return 0;
    }