【问题标题】:Permutation of a number's digits数字的数字排列
【发布时间】:2025-12-03 06:40:01
【问题描述】:

考虑将数字 194 声明为类型 int 是否有可能像其他整数一样有效地获得它的数字排列?
数量:194
419 int
491 int
第914章 第941章

我正在使用 next_permutation 但它仅适用于数组。所以我认为将 int 转换为 int 数组(?!)然后将排列作为数组获取并将其转换为它是不明智的。

有什么建议吗?

【问题讨论】:

  • "...我认为这样做是不明智的..." — 为什么不呢?
  • 我认为将 int 转换为 int 数组然后找到一个排列数组并转换回 int 是没有意义的。虽然,如果我找不到任何解决方案,我会这样做
  • 我不认为你能做的比 link 将你的 int 分解成数字并使用 next_permutation 做得更好

标签: c++ performance algorithm permutation


【解决方案1】:

置换数字基本上是字符串运算,而不是(简单的)数学运算。转换为数组(字符串)然后使用next_permutation() 听起来比尝试用数学方法更明智。

这是数学版本 - 没有保存中间值:

int a = 194;
int b = (a / 100)       * 100 + (a % 10)        * 10 + ((a / 10) % 10) * 1; // 149
int c = (a % 10)        * 100 + ((a / 10) % 10) * 10 + (a / 100)       * 1; // 491
int d = (a % 10)        * 100 + (a / 100)       * 10 + ((a / 10) % 10) * 1; // 419
int e = ((a / 10) % 10) * 100 + (a / 100)       * 10 + (a % 10)        * 1; // 914
int f = ((a / 10) % 10) * 100 + (a % 10)        * 10 + (a / 100)       * 1; // 941

使用中间值,更容易看到发生了什么(除了这次我为bf 生成了不同的分配)。

int a = 194;
int d1 = a / 100;
int d2 = (a / 10) % 10;
int d3 = a % 10;

int a = d1 * 100 + d2 * 10 + d3 * 1; // 194
int b = d1 * 100 + d3 * 10 + d2 * 1; // 149
int c = d2 * 100 + d1 * 10 + d3 * 1; // 914
int d = d2 * 100 + d3 * 10 + d1 * 1; // 941
int e = d3 * 100 + d1 * 10 + d2 * 1; // 419
int f = d3 * 100 + d2 * 10 + d1 * 1; // 491

使用next_permutation()机制;它将推广到 4 位、5 位和 N 位数字,而这不会。

【讨论】:

  • 感谢您的精彩回答,我会尝试字符串转换
【解决方案2】:

您首先必须先提取每个小数位的值:要么将其转换为字符数组 (itoa()),要么编写一个小的 for 循环,将数字除以 10 的幂。一旦你有了数字分开,你可以写一个循环来生成排列。

【讨论】:

  • 所以你不建议 next_permutation()?
【解决方案3】:

获取 十进制 位的排列将需要您以小数的形式与数字进行交互,因此 2 的幂操作在这里可能没有太大帮助。

我的建议是:

1. Convert number to string
2. Set up the string as a circular buffer
3. Step through the buffer progressively (each increment of the index into the circular buffer will give you one permutation)
4. Reconstruct the number from the "new" arrangement of the characters representing the digits
5. Repeat for the length of the string.

除非您在缓慢/资源受限的环境中运行,否则我不会试图过度考虑除此之外的问题。

编辑:

正如 cmets 中所指出的,这不会生成所有排列,为此需要在重复该过程的末尾添加另一个步骤,但索引变量的增量会逐渐增大。

【讨论】:

  • 您不会生成所有排列。 419 -> 194 -> 941,但不是 491