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

时间:2013-10-29 07:45:00

标签: c binary permutation

请帮我解决这个任务: 生成长度为n的所有二进制字符串,并设置k位。(需要在C上写入) 例如:

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;
}

8 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

你的代码很乱;)

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

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

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

#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-string而不是整数数组。在这种情况下更容易使用。

如果你想使用整数数组,我建议你添加一个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;
}

答案 2 :(得分:0)

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

# 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;
}

答案 3 :(得分:0)

试试这个

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

答案 4 :(得分:0)

//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);
    }
}

答案 5 :(得分:0)

这是递归解决方案

#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;
 }

答案 6 :(得分:-1)

#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;
}

答案 7 :(得分:-1)

  

**如果复杂性无关紧要,您可以使用以下代码在java中完成。这将在o(2 ^ n)中提供所需的输出。这里我找到了大小为n的数组中给定n位的0和1的所有组合。如果K位被设置,我已经计算了1的数量present使用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);
        }

}