生成所有长度为 n 且设置了 k 位的二进制字符串。(需要写在 C 上)

Posted

技术标签:

【中文标题】生成所有长度为 n 且设置了 k 位的二进制字符串。(需要写在 C 上)【英文标题】:Generate all binary strings of length n with k bits set.(need to write on C) 【发布时间】:2013-11-08 06:22:09 【问题描述】:

请帮我解决这个任务: 例如:

n=5
k=3
11100
00111
11010
01011
**01110
11001
10011
**01101
**10110
10101

** 无法生成这些排列

代码:

#include <stdio.h>
#define N 10
int main (void)

int mas[N]=0,kst,m,n1,z,a,b;
printf("\n\nVvedit` rozmirnist` masyvu: ");
scanf("%d",&kst);
printf("\n\nVvedit` kil`kist` odynyc`: ");
scanf("%d",&n1);
for(m=0;m1;m++)
   mas[m]=1;
for(m=0;m<kst;m++)
   printf("%d",mas[m]);
printf("\n");
for(m=0;m<n1;m++)
   for(z=0;z<(kst-1);z++)
     if((mas[z]==1) && (mas[z+1]==0))
     a=mas[z];
     mas[z]=mas[z+1];
     mas[z+1]=a;
     for(b=0;b<kst;b++)
        printf("%d",mas[b]);
printf("\n");

      
  

return 0;

【问题讨论】:

您好,欢迎来到 ***.com。请花一些时间阅读the help pages,尤其是名为"What topics can I ask about here?" 和"What types of questions should I avoid asking?" 的部分。更重要的是,请阅读the Stack Overflow question checklist。您可能还想了解SSCCE 是什么。 我给了一些链接检查一下。还有一件事在这里提问之前请尝试至少按时在 Internet(Google) 上搜索。geeksforgeeks.org/…***.com/questions/9148543/… 看到这样的代码,每天都更爱 C++:coliru.stacked-crooked.com/a/0dfd78620abdd1ff 【参考方案1】:

我已经解决了这个问题!请在下面找到我的代码!希望对您有所帮助。

#include<stdio.h>

int NumberOfBitsSet(int number)

    int BitsSet = 0;

    while(number != 0)
    

        if(number & 0x01)
        
            BitsSet++;
        
        number = number >> 1;
    

    return BitsSet;


void PrintNumberInBinary(int number, int NumBits)

    int val;
    val = 1 << NumBits; // here val is the maximum possible number of N bits with only MSB set

    while(val != 0)
    
        if(number & val)
        
            printf("1");
        
        else
        
            printf("0");
        

        val = val >> 1;
    


int main()

    int n,k,i;
    int max,min;
    printf("enter total number of bits and number of bits to be set:\n");
    scanf("%d %d", &n, &k);

    min = ((1 << k) - 1); //min possible values with k bits set
    max = (min << (n-k)); //max possible value with k bits set!
    //printf("%d %d", min, max);
    for(i=0; i<= max; i++)
    
        if(!(i<min))
        
            if(NumberOfBitsSet(i) == k)
            
                PrintNumberInBinary(i, (n-1));
                printf("\n");
            
        
    

    return 0;

【讨论】:

太棒了!我知道我问的太多了,但是你能用递归的方式写这个程序吗? 可以使用for(i=min; i&lt;= max; i++),完全去掉if语句if(!(i&lt;min))【参考方案2】:

你的代码一团糟;)

说真的:用代码解决任务的第一条规则是编写干净的代码,使用合理的变量命名等。

对于这样的任务,我建议using this。

现在到您的示例代码:它不会编译,并且很难阅读您要执行的操作。格式化并带有一些 cmets:

#include <stdio.h>

#define N 10

int main(void)

        int mas[N] = 0;
        int kst, m, n1, z, a, b;

        /* Read width ? */
        printf("\n\nVvedit` rozmirnist` masyvu: ");
        scanf("%d", &kst);
        /* Read number of bit's set? */
        printf("\n\nVvedit` kil`kist` odynyc`: ");
        scanf("%d", &n1);

        /* m1 is not defined, thus the loop give no meaning. 
         * Guess you are trying to set "bits" integers to 1.
         */
        for (m = 0; m1; m++)
                mas[m] = 1;

        /* This should be in a function as 1. You do it more then once, and
         * 2. It makes the code much cleaner and easy to maintain.
         */
        for (m = 0; m < kst; m++)
                printf("%d", mas[m]);
        printf("\n");

        for (m = 0; m < n1; m++) 
                for (z = 0; z < (kst - 1); z++) 
                        if ((mas[z] == 1) && (mas[z + 1] == 0)) 
                                a = mas[z];            /* Same as a = 1; */
                                mas[z] = mas[z + 1];   /* Same as mas[z] = 0; */
                                mas[z + 1] = a;        /* Same as mas[z + 1] = 1; */

                                /* Put this into a function. */
                                for (b = 0; b < kst; b++)
                                        printf("%d", mas[b]);
                                printf("\n");
                        
                
        

        return 0;


当人们不确定发生了什么时,广泛使用printf 是一种宝贵的工具。 这不是一个解决方案,(它基本上和你的帖子一样,但分开了),而是一个可能更容易使用的示例。我还使用 char 数组作为 C 字符串而不是整数数组。在这种情况下更容易使用。

如果您想使用整数数组,我建议您添加一个 print_perm(int *perm, int width) 辅助函数以将其从主代码中移除。

#include <stdio.h>

#define MAX_WIDTH 10

int get_spec(int *width, int *bits)

        fprintf(stderr, "Enter width    (max %-2d): ", MAX_WIDTH);
        scanf("%d", width);

        if (*width > MAX_WIDTH) 
                fprintf(stderr, "Bad input: %d > %d\n", *width, MAX_WIDTH);
                return 1;
        

        fprintf(stderr, "Enter set bits (max %-2d): ", *width);
        scanf("%d", bits);

        if (*bits > MAX_WIDTH) 
                fprintf(stderr, "Bad input: %d > %d\n", *bits, MAX_WIDTH);
                return 1;
        

        return 0;


void permutate(int width, int bits)

        char perm[MAX_WIDTH + 1];
        int i, j;

        /* Set "bits"  */
        for (i = 0; i < width; ++i)
                perm[i] = i < bits ? '1' : '0';

        /* Terminate C string */
        perm[i] = '\0';

        fprintf(stderr, "\nPermutations:\n");
        printf("%s\n", perm);

        for (i = 0; i < bits; ++i) 
                /* Debug print current perm and outer iteration number */
                printf("%*s LOOP(%d)   %s\n", 
                        width, "", i, perm
                );

                for (j = 0; j < (width - 1); ++j) 
                        if (perm[j] == '1' && perm[j + 1] == '0') 
                                perm[j] = '0';
                                perm[j + 1] = '1';

                                printf("%s j=%d print\n", 
                                        perm, j
                                );
                         else 
                                /* Debug print */
                                printf("%*s j=%d skip  %s\n", 
                                        width, "", j, perm
                                );
                        
                
        


int main(void)

        int width, bits;

        if (get_spec(&width, &bits))
                return 1;

        permutate(width, bits);

        return 0;

【讨论】:

【参考方案3】:

如果您想在不执行“迭代和检查”的情况下唯一地列出所有排列,您可以执行以下操作:

# Move peg x up m using s
# x is negative
# m is positive
def move(x, m, s):
    for i in range(1, m+1):
        s2 = list(s)

        s2[x] = 0
        s2[x - i] = 1

        print(s2)

        if x + 1 < 0:
            move(x+1, i, s2)

# Print all unique permutations of 
# n bits with k ones (and n-k zeros)
def uniqPerms(n, k):
    s = [0 for _ in range(n-k)] + [1 for _ in range(k)]

    print(s)
    move(-k, n-k, s)

if __name__ == '__main__':
    from sys import argv
    uniqPerms(int(argv[1]), int(argv[2]))

这个想法是你递归地增加 1,这样每个动作都会产生一个唯一的列表(因为 1 现在是以前没有的地方)。

你说它必须在 C 中:

#include <stdio.h>
#include <stdlib.h>

enum  n = 8 ;

struct string

    char str[n + 1];
;

void move(int x, int m, string s)

    for (int i = 0; i <= m; ++i)
    
        string s2 = s;
        s2.str[n + x] = '0';
        s2.str[n + x - i] = '1';
        printf("%s\n", s2.str);

        if (x + 1 < 0)
            move(x + 1, i, s2);
    


void uniqPerms(int k)

    string s;
    for (int i = 0; i < n - k; ++i)
        s.str[i] = '0';
    for (int i = n - k; i < n; ++i)
        s.str[i] = '1';
    s.str[n] = '\0';

    printf("%s\n", s.str);
    move(-k, n - k, s);


int main(int argc, char *argv[])

    uniqPerms(atoi(argv[1]));
    return 0;

【讨论】:

【参考方案4】:

试试这个

A[n-1]=0;
func(n-1);
A[n-1]=1;
func(n-1);

【讨论】:

【参考方案5】:
//Think simple people but please bear with me i love java

//Assume array A is globally defined

void Binary(int n)

    if(n<1)
    
        System.out.println(A);
    
    else
    
        A[n-1]=0;
        Binary(n-1);
        A[n-1]=1;
        Binary(n-1);
    

【讨论】:

【参考方案6】:

这是递归解决方案

#include <iostream>
#include <vector>

using namespace std;


char v[4];
int count = 0;

void printString()
    int i;
    for(i = 0; i < 4; i++)
        cout << v[i] << "  ";
    
    cout <<count <<  endl;
 


void binary(int n)
if(n < 0)
    if(count == 2)
        printString();

else
    v[n] = '0';
    binary(n - 1);
    v[n] = '1';
    count++;
    binary(n-1);
    count--;





int main()
binary(3);
return 0;
 

【讨论】:

【参考方案7】:
#include<stdio.h>
int main()
int n,k,i,j,a[50];
//lets suppose maximum size is 50
printf("Enter the value for n");
scanf("%d",&n);
printf("Enter the value for k");
scanf("%d",&k);
//create an initial bitstring of k 1's and n-k 0's;
for(i=0;i<n;i++)
if(k>0)    
   a[i]=1;
else
   a[i]=0;
k--;

for(i=0;i<n;i++)
if(a[i]==1)
for(j=0;j<n;j++)
if(j!=i&&a[j]==0)
a[j]=1;a[i]=0;
for(k=0;k<n;k++)printf("%d\n",a[k]);
a[i]=1; a[j]=0;

return 0;

【讨论】:

代码接近不可读。而且,结果甚至比 OP 提供的结果还要糟糕。 10 个中有 6 个排列。 太好了,我什至没有测试代码。我只是写了一些我想到的东西。它甚至工作!!!【参考方案8】:

**如果复杂性无关紧要,您可以使用以下在 java 中完成的代码。它将在 o(2^n) 中提供所需的输出。在这里,我找到了大小为 n 的数组中给定 n 位的 0 和 1 的所有组合。如果设置了 K 位,我已经计算了 1 的数量使用 countBits() 函数呈现的值等于 k。如果我打印了该数组。

public class GenerateAllStringOfNBitsWithKBitsSet 
     public static  int a[] =0,0,0,0,0;
     static int k=3;
     public static boolean countBits()
        int  y=0;
         for(int i=0;i<a.length;i++)   
           y += a[i] &  1 ;

         if(y==k)
             return true;
         return false;
       
        public static void gen(int n)
        
            if(n<1)
            
                if(countBits())
                System.out.println(Arrays.toString(a));

            
            else
             
                 a[n-1]=0;
                 gen(n-1);
                 a[n-1]=1;
                 gen(n-1);
            
        
        public static void main(String[] args) 


            GenerateAllStringOfNBitsWithKBitsSet.gen(a.length);
        


【讨论】:

它没有回答这个问题,它被问到并标记为语言 C。 它的意思是什么不能回答问题如果您有任何 java 编辑器只需运行相同的代码并查看答案并评论您的评论,我同意这不是为 C 标记的.但是有给定想法的人可以轻松地将其转换为c。

以上是关于生成所有长度为 n 且设置了 k 位的二进制字符串。(需要写在 C 上)的主要内容,如果未能解决你的问题,请参考以下文章

大水题(water)

生成一个二进制数列表,其中 n 位设置为 1

多项式如何转换二进制

求2^k进制数C++语言,带解释。。。。。。。

P2064进制转换

关于bitset