生成所有具有重复数字的组合

发布于 2024-12-12 06:26:20 字数 192 浏览 0 评论 0原文

我已经阅读这个网站足够长的时间了,知道不要隐瞒这是一项家庭作业。但我正在尝试编写一个代码,可以生成仅由 0 和 1 组成的字符串的所有可能组合。如果字符串的长度是n^2,那么就会有n个1,其余的都是0。长度始终是完全平方数。我正在用 C 进行编码,我一直在尝试在嵌套循环中完成它,但似乎可以通过递归方式更轻松地完成它,我只是不确定如何进行设置。任何提示或建议将不胜感激。

I've been reading this site long enough to know not to hide that this is a homework assignment. But I am trying to write a code that can generate all possible combinations of a string of only 0's and 1's. If the length of the string is n^2, then there will be n 1's and the rest will be 0's. The length is always a perfect square. I am coding in C and I have been trying to do it in nested loops but it seems like it could be done more easily in a recursive manner, I'm just not sure how to get that set up. Any tips or advice would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

逆光飞翔i 2024-12-19 06:26:20

伪代码:

myfun(pos,length, ones)
  if (length==0)
     pos='\0'
     #print, collect, whatever...
     return
  if (length>ones)
    pos='0'
    myfun(pos+1,length-1, ones)
  pos='1'
  myfun(pos+1, length-1, ones-1)

task(n)
  #allocate n^2 buffer
  myfun(buffer, n*n, n)

pseudocode:

myfun(pos,length, ones)
  if (length==0)
     pos='\0'
     #print, collect, whatever...
     return
  if (length>ones)
    pos='0'
    myfun(pos+1,length-1, ones)
  pos='1'
  myfun(pos+1, length-1, ones-1)

task(n)
  #allocate n^2 buffer
  myfun(buffer, n*n, n)
瑶笙 2024-12-19 06:26:20

我不确定这个问题是否适合递归。在 C(和大多数语言)中,每次调用函数时,都会创建一个堆栈帧并使用几个处理器周期和一块堆栈内存。此问题的任何递归解决方案都会创建 n^2 堆栈帧,即使递归本身仅添加一位信息。

下面概述了一个非常糟糕的解决方案。它不做什么:

  • 利用 n 始终是完全平方这一事实。
  • 以非常智能的方式使用内存
  • 释放它使用的任何内存
  • 甚至可能不起作用。 ;)

...但它可能会让您了解基本模式。

void foo(int zeros_left, int length_left, char *s)
{
    if (length_left == 0)
        printf("%s\n", s);
    else
    {
        if (zeros_left > 0)
        {
            char *next = malloc(strlen(s) + 2);
            strcpy(next, s);
            strcat(next, "0");
            foo(zeros_left - 1, length_left - 1, next);
        }

        if (zeros_left != length_left)
        {
            char *next = malloc(strlen(s) + 2);
            strcpy(next, s);
            strcat(next, "1");
            foo(zeros_left, length_left - 1, next);
        }
    }
}

I'm not sure that this problem lends itself to recursion. In C (and most languages), every time you call a function you create a stack frame and use a few processor cycles and a chunk of stack memory. Any recursive solution to this problem will create n^2 stack frames, even the the recursion itself is only adding one bit of information.

A really bad solution is outlined below. What it doesn't do:

  • Exploit the fact that n is always a perfect square.
  • Use memory in a very intelligent way
  • Frees any of the memory it uses
  • Might not even work. ;)

...but it might give you an idea of the basic pattern.

void foo(int zeros_left, int length_left, char *s)
{
    if (length_left == 0)
        printf("%s\n", s);
    else
    {
        if (zeros_left > 0)
        {
            char *next = malloc(strlen(s) + 2);
            strcpy(next, s);
            strcat(next, "0");
            foo(zeros_left - 1, length_left - 1, next);
        }

        if (zeros_left != length_left)
        {
            char *next = malloc(strlen(s) + 2);
            strcpy(next, s);
            strcat(next, "1");
            foo(zeros_left, length_left - 1, next);
        }
    }
}
爱已欠费 2024-12-19 06:26:20

对问题进行递归建模的关键是将问题的较大版本分解为与同一问题的较小版本相结合的简单计算,以及终止递归的简单情况。

在这种情况下,问题是:

  • 对于非负的M和N,输出所有长度为M且恰好包含N个1的字符串。

您可以将其分解为:

  • 如果M = 0,则输出一个空字符串;否则
  • 输出长度为 M-1 且恰好包含 N 1 的所有字符串,每个字符串都以 0 为前缀;如果
  • N > 0,然后输出长度为 M-1 且正好包含 N-1 1 的字符串,每个字符串都以 1 为前缀。

这里,M = 0 是终止递归的简单情况。将以上内容转化为代码相当简单。

The key to modelling a problem recursively is to break a larger version of the problem into a simple calculation combined with a smaller version of the same problem, and a trivial case that terminates the recursion.

In this case, the problem is:

  • For non-negative M and N, output all strings of length M that contain exactly N 1s.

You can break this down into:

  • If M = 0, then output an empty string; otherwise
  • Output all strings of length M-1 that contain exactly N 1s, prefixing each with an 0; and
  • If N > 0, then output all strings of length M-1 that contain exactly N-1 1s, prefixing each with a 1.

Here, M = 0 is the trivial case that terminates the recursion. Turning the above into code is reasonably simple.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文