algorithm - 重复的递归排列

标签 algorithm math recursion

我正在尝试编写一个递归函数,它通过给定列表的重复获取所有排列。

Eg. set = ABC
1. AAA
2. AAB
3. AAC
4. ABA 
N. CCC

我想要这个代码的递归版本,这样我就可以获得任何大小的集合的排列:

for i=0; i<S.size(); i++ {
   for j=0; j<S.size(); j++ {
      for k=0; k<S.size(); k++ {

         perm[0] = S[i];
         perm[1] = S[j];
         perm[2] = S[k];
         permutations.push(combo);

      }
   }
}

我在解决这个问题时遇到了一些麻烦。到目前为止,我在想我需要找到何时达到任意深度以停止重复诅咒。

编辑:我更喜欢伪代码解决方案,我没有在 C++ 中实现它

最佳答案

鉴于您希望输出 AABABA,您正在寻找排列而不是组合。特别是,您正在寻找一组大小 k 的唯一排列,其中元素是从一组 n 标记中替换绘制的。组合数为 n+k-1Ck 而排列数为 nk

说明这两个概念的伪代码:

build_combinations (tokens, set_size)
  Arrangements combos
  if (set_size == 0)
    combos.add ("")
  else
    Comment: tail_substrings of "ABC" is ("ABC", "BC", "C").
    foreach tail (tail_substrings (tokens))
      foreach sub_combo (build_combinations (tail, set_size-1))
        combos.add (tail.first() + sub_combo)
  return combos

build_permutations (tokens, set_size)
  Arrangements perms
  if (set_size == 0)
    perms.add ("")
  else
    sub_perms = build_permutations (tokens, set_size-1)
    foreach token (tokens)
      foreach perm (sub_perms)
        perms.add (cur_token + *rem_iter)
  return perms

一个有效的 C++ 实现:

#include <string>
#include <vector>

typedef std::string::const_iterator StringIterator;
typedef std::vector<std::string> Arrangements;
typedef Arrangements::const_iterator ArrangementsIterator;

Arrangements build_combinations (const std::string & tokens, unsigned set_size)
{
  Arrangements combos;
  if (set_size == 0) {
    combos.push_back ("");
  }   
  else {
    for (StringIterator token_iter = tokens.begin();
         token_iter != tokens.end();
         ++token_iter) {
      std::string cur_token(1, *token_iter);
      std::string rem_tokens(token_iter, tokens.end());
      Arrangements rem_combos = build_combinations (rem_tokens, set_size-1);
      for (ArrangementsIterator rem_iter = rem_combos.begin();
           rem_iter != rem_combos.end();
           ++rem_iter) {
         combos.push_back (cur_token + *rem_iter);
      }
    }
  }   
  return combos;
}   

Arrangements build_permutations (const std::string & tokens, unsigned set_size)
{
  Arrangements perms;
  if (set_size == 0) {
    perms.push_back ("");
  }
  else {
    Arrangements rem_perms = build_permutations (tokens, set_size-1);
    for (StringIterator token_iter = tokens.begin();
         token_iter != tokens.end();
         ++token_iter) {
      std::string cur_token(1, *token_iter);
      for (ArrangementsIterator rem_iter = rem_perms.begin();
           rem_iter != rem_perms.end();
           ++rem_iter) {
         perms.push_back (cur_token + *rem_iter);
      }
    }
  }
  return perms;
}

关于algorithm - 重复的递归排列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7292370/

相关文章:

c - 下面的程序如何花费 O(n!) 时间?

PHP:计算字符串中的数学函数 f(x)

Python 代码卡在 Iterating 中,尽管它找到了解决方案

algorithm - 启发式地解决有额外约束的旅行推销员的想法

java - 如何将数学符号(例如 R^n)放入 Java 字符串?

java - AS3/Java - 通过知道其他两点和线段长度找到三角形的点

php - 从类别树中清除空类别

c++ - 递归:将字符串中的 e 换成 a

xml - XQuery 简单递归查询子级到 XML 中的顶级父级

algorithm - 移动通过坦克的零件。最短路径算法