从给定的数字计算所有可能的数字

Compute all possible numbers from given digits

本文关键字:数字 有可能 计算所      更新时间:2023-10-16

问题很简单。从给定的一组数字(最多有10个数字)中,计算出这些数字可以构成的所有数字(一个数字可以在集合中出现多少次)

首先,我想到使用蛮力并遍历所有可能的组合,但组合的数量与N的阶乘一样大,其中N是位数。即使这是可能的我怎么能运行所有可能的组合而不使用10个for循环?

第二,我试着把所有这些数字放在一个字符串中,从字符串中删除一个,并放在末尾,继续这样尝试,但这可能不会给出任何可能的组合,即使它有,我不相信它会在一个合理的时间。

我相信一定有一种更快更好的算法从给定的一组数字中获得所有可能的数字。

我在网上找到了一个代码,它是:

#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;
}

我的方法可能看起来有点复杂,但我将首先给出一个概述和一个非常简单的示例代码(来自错误的语言)。

就像你说的,你基本上需要所有元素的排列。所以最明显的方法是使用一个库函数,它已经做到了这一点。也许std::next_permutation(我将使用intertools)。排列(我的简单示例)。但是,您指定输入集中可能有重复的元素,这违反了对该工具的约束。

因此,我的方法是在一组唯一键和元素(数字)之间构建一个映射,这些元素可能有重复项。对于您所描述的少量数字,最简单的方法是使用单个字符作为键,将它们映射(当然是通过字典)到给定的元素(数字)。一个方便的方法是通过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()函数的方式打印,那么您可能需要稍微改变一下操作方式。(这些是实现细节)。

那么,您可以创建这样的映射,遍历其键的排列,并在返回/打印结果时执行映射解引用吗?