我需要获取给定集合的所有可能组合。例如,给定:[1,4,7],得到的组合应为:
我尝试使用next_permutation
方法,但这不是我想要的(这不会返回111,144,717等值)。
那么我有什么方法可以在C ++中做到这一点?请注意,我是一个完全的初学者。
提前致谢。
答案 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;
}