问题很简单。从给定的一组数字(最多10位数)开始,计算可以形成这个数字的所有数字(一个数字可以被使用多次,它包含在集合中)。
拳头我想到使用蛮力并运行所有可能的组合,但组合的数量与N的阶乘一样大,其中N是数字的位数。即使有可能,如何使用10 for for循环来运行所有可能的组合?
其次我尝试将所有这些数字放在一个字符串中并从字符串中删除一个并放在最后并继续尝试这样,但这可能不会给出任何可能的组合,即使它确实如此我也不会相信它会在合理的时间内完成。
我确信必须有一个更快更好的算法来从一组给定的数字中获取所有可能的nubmers。
我在互联网上找到了一个代码,它是:
#include <iostream>
#include <algorithm>
using namespace std;
int main () {
int noOfDigits;
cin >> noOfDigits;
int myints[noOfDigits];
for(int i = 0; i<noOfDigits; i++)
{
cin >> myints[i];
}
sort (myints,myints+3);
do {
for(int i = 0; i<noOfDigits;i++)
{
cout << myints[i];
}
cout << endl;
} while ( next_permutation(myints,myints+noOfDigits) );
return 0;
}
答案 0 :(得分:0)
我的方法可能看起来有点复杂,但我会首先给出概述和一些非常简单的示例代码(来自错误的语言)。
正如你所说,你从根本上想要所有元素的排列。所以显而易见的方法是使用已经执行此操作的库函数。也许std::next_permutation(我将使用intertools.permutations作为我的简单示例)。但是,您指定输入集中可能包含重复的元素,这违反了该工具的约束。
所以我的方法是在一组唯一键和我们的元素(数字)之间建立一个映射,以及它们可能的重复。对于您描述的少量数字,最简单的方法是使用单个字符作为键,将它们(通过字典,当然)映射到给定的元素(数字)。一种方便的方法是通过string.printable。因此,给定一个名为 mydigits 的元组,列表或其他“数字”序列,我们可以将映射构建为:
#!python
import string
digit_mapping = dict([(y,x) for x,y in zip(mydigits,string.printable)])
从那里我们所要做的就是迭代排列并将键映射回原始的“数字”(在这种情况下是那些“数字”的字符串表示
#!python
for i in itertools.permutations(digit_mapping.keys()):
perm = ''.join([str(digit_mapping[x]) for x in i])
print perm,
...当然,如果你想以某种特定顺序打印这些排列而不是以 .keys()方法和中的任何方式打印这些排列,你可能需要稍微改变一下。 itertools.permutations()函数。 (这些是实施细节)。
那么,您可以创建这样的映射,迭代其键的排列,并在返回/打印结果时执行映射解除引用吗?