我正在编写一些代码并最终解决了这个问题。我有N个产品,我必须形成这些产品的所有可能组合,形成产品目录并找到一些属性,如价格。为了做到这一点,我必须从给定的产品中形成产品目录(详尽,但不允许重复)。这样做有标准化的算法吗?请注意,目录可以包含任何正数的产品。
答案 0 :(得分:4)
组合可以用位向量表示。如果设置了某个位,则该元素将出现在组合中。
所以你只需要enumarte从1到2 ^ N-1(从0000001,最后一个元素到1111111,所有元素都存在)的所有数字,并代表一个可能的组合。
答案 1 :(得分:2)
从给定字符串中打印所有字符组合的简单实现:
void print_combination(char* str, char* buffer, int len, int num, int pos)
{
if(num == 0)
{
std::cout << buffer << std::endl;
return;
}
for(int i = pos; i < len - num + 1; ++i)
{
buffer[num - 1] = str[i];
print_combination(str, buffer, len, num - 1, i + 1);
}
}
int main()
{
char str[] = "abcde";
char buffer[6];
for(auto i = 1u; i <= sizeof(str); ++i)
{
buffer[i] = '\0';
print_combination(str, buffer, 5, i, 0);
}
}
非常简单但可能存在性能问题。如果可以的话,请接受它。
如果您正在寻找排列(我无法从您的描述中得知),我在“计算机编程艺术”中实现了算法:
template <typename Iter>
bool next_permutation(Iter start, Iter end)
{
if(start == end)
return false;
Iter i = start + 1;
if(i == end)
return false;
i = end - 1;
while(true)
{
Iter ii = i;
--i;
if(*i < *ii)
{
Iter j = end;
while(*i >= *--j);
std::iter_swap(i, j);
std::reverse(ii, end);
return true;
}
if(i == start)
{
std::reverse(start, end);
return false;
}
}
}
int main()
{
char str1[] = "abcde";
do
{
std::cout << str1 << std::endl;
} while(next_permutation(&str1[0], &str1[5]));
}
它非常有效,C ++ stl算法使用相同的算法。
答案 2 :(得分:2)
您可以在python中使用itertools.combinations以下列方式执行此操作:
import itertools
products = ['p1', 'p2', 'p3', 'p4']
for L in range(1, len(products)+1):
for subset in itertools.combinations(products, L):
print(subset)
结果如何:
('p1',)
('p2',)
('p3',)
('p4',)
('p1', 'p2')
('p1', 'p3')
('p1', 'p4')
('p2', 'p3')
('p2', 'p4')
('p3', 'p4')
('p1', 'p2', 'p3')
('p1', 'p2', 'p4')
('p1', 'p3', 'p4')
('p2', 'p3', 'p4')
('p1', 'p2', 'p3', 'p4')
受this answer of @dan-h启发的解决方案。
答案 3 :(得分:1)
计算机程序设计艺术的前几部分,第一卷。 3,排序和搜索非常详细地讨论了反转和置换(集合和多集)。在这种情况下,重要的是在理论上考虑一下,看看那里有什么。代码将遵循,但如果这是“休闲时间编码”,为什么不包括“休闲时间理论”呢? Betcha它会很酷,你会知道什么,但你也会知道这些为什么!