如何列出所有的变化没有STL c++

How to list all of variations without STL C++

本文关键字:STL c++ 变化 何列出      更新时间:2023-10-16

我卡住了

有人能帮我吗?我的问题是,我不知道,如何使清单变化没有STL。

的例子:

 Input : a[3] = {1, 2, 3}
 n = 2

输出:1 1;2 1;3 1;1 - 2;2 2;3 - 2;1 3;2 3;3 3;

我不能使用循环,因为输入可以和我声明的一样大,而且n也是一个变量。

谢谢:)

既然我们在发布剧透,让我发布一个我最初实现的算法的优化版本,以回答Ruby中的数字运算(需要优化)

玩得开心

#include <stdio.h>
#include <string.h>
inline void recursive_permute2(const char* b, char* const m, char* const e, const char* domain)
{
    if (m<e)
        for (; *domain; ++domain)
        {
            *m = *domain;
            recursive_permute2(b, m+1, e, domain);
        }
    else
        puts(b);
}
inline void recursive_permute(char* const b, char* const e, const char* const domain)
{
    *e = '';
    recursive_permute2(b, b, e, domain);
}
int main()
{
    const int n = 2;
    char buf[n+1];
    recursive_permute(buf, buf+n, "123");
}

我曾经建议您从snippets.org获取这篇文章,但它现在已经离开了这个领域(它的前任管理员Bob Stout似乎也离开了这个领域)。正如评论中所指出的那样,我并没有写这篇文章,但与大多数帖子不同的是,它至少在一定程度上经过了测试。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*  chouse_n ( char *strng, int length) returns a pointer to a string of   */
/*  length characters chosen from "strng" , duplicate chars in "strng" are */
/*  significant.  Strings are generated in lexical order.                  */
/*  First call, call with *strng. each subsiquent call, call with NULL,    */
/*  returns one combination. Calls after all combinations have been        */
/*  returned return NULL.  Will return NULL for errors.                    */
/*  not very defensive (i.e. WILL BREAK)                                   */
/*  dave chapman aug '91  released to public domain                        */
char *chouse_n( char *strng, int length);
char *chouse_n( char *strng, int length)
{
      static char *str;
      static char *curr;
      static char *pos;       /* for each char in curr(ent string),
                                 its pos in str                            */
      static int  counts[256];
      int i,j;
      if (0 >= length)
            return NULL;
      if (NULL != strng)
      {
            str = malloc(strlen(strng)); /* first call, prep string for use */
            curr = malloc(2 * length + 1);
            pos = curr + length +1;
            for (i = 0; i < 256; counts[i++] = 0)
                  ;
            for (i = 0; strng[i]; i++)
                  counts[strng[i]]++;
            for (i = 1, j = 0; i < 256; i++)
            {
                  if (counts[i])
                  {
                        str[j] = i;
                        counts[j++] = counts[i];
                  }
            }
            str[j] = '';      /* str is string of distinct chars in order */
                                /* counts[] holds count of each char        */
            /* take first length chars */
            for (i = 0,j = 0; i < length; i++)
            {
                  curr[i] = str[j];
                  pos[i] = j;
                  if (!(--counts[j]))
                        j++;
            }
            curr[i] = '';
            return curr;
      }
      /* if called with "mississippi",5;
         str -> "imps"
         curr -> "iiiim"
         counts -> 0,0,2,4;
         pos -> 0,0,0,0,1;   */
      /* go back to front */
      for (j = length; j > 0;)
      {
            counts[ pos[--j]]++;                      /* "replace" char */
            /* look for a new char for curr posit. */
            for ( i = ++pos[j]; str[i] && ! counts[i]; i++)
            ;
            if (0 != (curr[j] = str[i]))              /* found a char   */
            {
                  --counts[i];
                  pos[j] = i;
                  /* placed char, fill out rest of string  */
                  for (++j, i = 0; j < length; j++)
                  {
                        for ( ; !counts[i]; i++)
                              ;
                        curr[j] = str[i];       /* first available char */
                        --counts[i];
                        pos[j] = i;
                  }
                  return curr;
            }
            /* no more chars for this pos ; go back one */
      }
      /*  done */
      return NULL;
}
main()
{
      char  *str = "aabbccdd";
      int i,j;
      j = 0;
      i =  5;
      puts(chouse_n( str, i));
      while (NULL != (str = chouse_n(NULL, i)))
      {
            ++j;
            printf(" %s  %dn",str,j);
      }
      return 0;
}

这有点像家庭作业,所以我不想只给你一小段代码。但我可以试着用算法引导你走上正确的道路。

让我们从一个初始为空的数组堆栈开始。现在,对于a的每个元素,创建一个新的列表来保存它。现在我们有三个列表:[1], [2], [3]。将每个列表推入堆栈或队列以保存它们。现在,从堆栈中取出一个。我们先得到[1]。这使得堆栈保留[2][3]。检查刚刚弹出的元素([1])。它够长吗?不。你要两件东西,而它只有一件。所以现在您再次遍历a的所有元素,并将每个元素添加到您弹出的节点的新副本中。这将为您提供三个新节点:[1,1][1,2][1,3]。将这些新节点也推到堆栈上。剩下的堆栈包含[1,1][1,2][1,3][2][3]。弹出下一个节点。在本例中,它是[1,1]。该节点的长度等于n,因此打印它。现在再弹一次。得到[1,2]。再次打印出来。重复打印[1,3]。当你再次弹出时,你会得到[2]。这还不够长,所以我们将a中的每个元素与当前节点组合,并将它们压入堆栈以产生[2,1], [2,2][2,3]

继续这个过程,直到堆栈为空,您将打印从数组中提取的n项的每个排列。我所描述的是使用手动管理的堆栈将递归算法展开为迭代算法。如果愿意,您可以使用递归调用而不是堆栈来模拟相同的过程。无论哪种方式,你都必须从根本上考虑递归来解决问题。