Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C中为0,1使用递归生成4位二进制组合?_C_Algorithm_Recursion_Permutation_Combinations - Fatal编程技术网

如何在C中为0,1使用递归生成4位二进制组合?

如何在C中为0,1使用递归生成4位二进制组合?,c,algorithm,recursion,permutation,combinations,C,Algorithm,Recursion,Permutation,Combinations,对于此阵列,请尝试以下操作: void rollover(int val,int count) { if(count==0) { return; } printf("%d ",val); count--; rollover(val,count); } int main() { int arr[]={0,1}; for(int i=0;i<=1;i++) { rollover(arr[i],4

对于此阵列,请尝试以下操作:

void rollover(int val,int count) {  
    if(count==0) {
        return;
    }
    printf("%d ",val);
    count--;
    rollover(val,count);    
}
int main() {
    int arr[]={0,1};
    for(int i=0;i<=1;i++) {
        rollover(arr[i],4);
    }
    printf("\n");
    return 0;
}
无法理解如何编写rec函数。我花了几个小时来解决它。 有人能帮忙写这个函数吗

我正在/正在尝试做一些类似于下面发布的G_G的事情。 如何编写这样的递归函数? 我必须用一个for循环调用递归函数,还是用两个for循环调用递归函数,还是应该调用递归函数两次?例如:

void rollover(int val,int count) {  
    if(count==0) {
        return;
    }
    printf("%d ",val);
    count--;
    rollover(val,count);
    //.. do something if necessary ..
    rollover(val,count);
    //.. do something if necessary ..
}
l1 = [0]
l2 = [ [1,1] , [1,0] ]
then 
f1(l1,l2) = [ [0,1,1] ,[0,1,0]]


    def f1(l1:List[Int],l2:List[List[Int]]): List[List[Int]] = l2.map{ r=> l1:::r}
l1 = [ [0] , [1]]
l2 = [ [1,0], [1,1] ]
f(l1,l2) = [ [0,1,0],[0,1,1], [1,1,0],[1,1,1] ]


    def f(l1:List[List[Int]],l2:List[List[Int]]): List[List[Int]] = l1.map{ r=> f1(r,l2)} flatten

只要遍历深度为4的二叉树,向左是0,向右是1

tr(int dep, int val)
{
   if(dep == 4)
   {
     printf("\n");
   }
   else
   {
     printf("%d", val);
     tr(dep+1, 0); // going left
     tr(dep+1, 1); // going right
   }

   return;
}

int main()
{
   tr(0,0);
}

可以使用
+1

void f(unsigned int x)
{
   printf("%u%u%u%u\n",
          (x>>3)&0x1,
          (x>>2)&0x1,
          (x>>1)&0x1,
          x&0x1);
   if(x==0xF) return;
   else f(x+1);
}

int main(void)
{
    f(0);
}
执行:

$ ./test
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
vector<string> ve,ve1;
int main(int argc, char const *argv[])
{
    /* code */
    int n;
    cin>>n;
    generate("0",n,true);
    generate("1",n,false);
    for(int i=0;i<ve.size();i++){
        cout<<ve[i]<<endl;
    }
    for(int i=0;i<ve1.size();i++){
        cout<<ve1[i]<<endl;
    }
    return 0;
}
void generate(string s,int n,bool b){
    if(n==1){
        if(b==true){
            ve.push_back(s);
        }
        else{
            ve1.push_back(s);
        }
        return;
    }else{
        generate(s+"0",n-1,b);
        generate(s+"1",n-1,b);
    }
}

最简单的解决方案:二进制转换,无递归

for(int i = 0; i < 16: ++i) {
    printf("%u%u%u%u", i/8%2, i/4%2, i/2%2, i%2);  
}
void char_buffer_rec(char number[4], int n) {
    if(n > 0) {
        number[4-n] = '0';
        char_buffer_rec(number, n - 1);
        number[4-n] = '1';
        char_buffer_rec(number, n - 1);
    }
    else {
        printf("%s\n", number);
    }
}
struct Node {
    int val;
    struct Node *left, *right;
};

void build_tree(struct Node* tree, int n) {
    if(n > 0) {
        tree->left = (Node*)malloc(sizeof(Node));
        tree->right= (Node*)malloc(sizeof(Node));
        tree->left->val = 0;
        build_tree(tree->left, n - 1);
        tree->right->val = 1;
        build_tree(tree->right, n - 1);
    }
    else {
        tree->left = tree->right = NULL;
    }
}

void print_tree(struct Node* tree, char* buffer, int index) {
    if(tree->left != NULL && tree->right != NULL) {
        sprintf(buffer+index, "%u", tree->val);
        print_tree(tree->left, buffer, index+1);
        sprintf(buffer+index, "%u", tree->val);
        print_tree(tree->right, buffer, index+1);
    }
    else {
        printf("%s%u\n", buffer, tree->val);
    }
}
使用
char*
缓冲区的递归解决方案,无二进制转换

for(int i = 0; i < 16: ++i) {
    printf("%u%u%u%u", i/8%2, i/4%2, i/2%2, i%2);  
}
void char_buffer_rec(char number[4], int n) {
    if(n > 0) {
        number[4-n] = '0';
        char_buffer_rec(number, n - 1);
        number[4-n] = '1';
        char_buffer_rec(number, n - 1);
    }
    else {
        printf("%s\n", number);
    }
}
struct Node {
    int val;
    struct Node *left, *right;
};

void build_tree(struct Node* tree, int n) {
    if(n > 0) {
        tree->left = (Node*)malloc(sizeof(Node));
        tree->right= (Node*)malloc(sizeof(Node));
        tree->left->val = 0;
        build_tree(tree->left, n - 1);
        tree->right->val = 1;
        build_tree(tree->right, n - 1);
    }
    else {
        tree->left = tree->right = NULL;
    }
}

void print_tree(struct Node* tree, char* buffer, int index) {
    if(tree->left != NULL && tree->right != NULL) {
        sprintf(buffer+index, "%u", tree->val);
        print_tree(tree->left, buffer, index+1);
        sprintf(buffer+index, "%u", tree->val);
        print_tree(tree->right, buffer, index+1);
    }
    else {
        printf("%s%u\n", buffer, tree->val);
    }
}
用法:

仅使用
int
的递归解决方案,无缓冲区,无二进制转换

void int_ten_rec(int number, int tenpower) {
    if(tenpower > 0) {
        int_ten_rec(number, tenpower/10);
        int_ten_rec(number + tenpower, tenpower/10);
    }
    else {
        printf("%04u\n", number);
    }
}
用法:

此解决方案的另一个版本替换了
tenpower
width
bitwidth
,根据长度变量将printf
width
替换为变量填充<代码>长度可以定义为新参数、程序常数等

void int_rec(int number, int bitwidth) {
    static int length = bitwidth;
    int i, n;
    if(bitwidth > 0) {
        int_rec(number, bitwidth-1);
        /* n := 10^(bitwidth-2) */
        for(i=0,n=1;i<bitwidth-1;++i,n*=10);
        int_rec(number + n, bitwidth-1);
    }
    else {
        /* i := number of digit in 'number' */
        for(i=1,n=number;n>=10;++i,n/=10);
        /* print (length-i) zeros */
        for(n=i; n<length; ++n) printf("0");
        printf("%u\n", number);
    }
}
树解决方案,使用
char*
缓冲区递归,无二进制转换

for(int i = 0; i < 16: ++i) {
    printf("%u%u%u%u", i/8%2, i/4%2, i/2%2, i%2);  
}
void char_buffer_rec(char number[4], int n) {
    if(n > 0) {
        number[4-n] = '0';
        char_buffer_rec(number, n - 1);
        number[4-n] = '1';
        char_buffer_rec(number, n - 1);
    }
    else {
        printf("%s\n", number);
    }
}
struct Node {
    int val;
    struct Node *left, *right;
};

void build_tree(struct Node* tree, int n) {
    if(n > 0) {
        tree->left = (Node*)malloc(sizeof(Node));
        tree->right= (Node*)malloc(sizeof(Node));
        tree->left->val = 0;
        build_tree(tree->left, n - 1);
        tree->right->val = 1;
        build_tree(tree->right, n - 1);
    }
    else {
        tree->left = tree->right = NULL;
    }
}

void print_tree(struct Node* tree, char* buffer, int index) {
    if(tree->left != NULL && tree->right != NULL) {
        sprintf(buffer+index, "%u", tree->val);
        print_tree(tree->left, buffer, index+1);
        sprintf(buffer+index, "%u", tree->val);
        print_tree(tree->right, buffer, index+1);
    }
    else {
        printf("%s%u\n", buffer, tree->val);
    }
}
用法:

但这会在每行的开头打印一个额外的
0
,为了避免这种情况,请构建两个较小的树:

    Node* tree0 = (Node*)malloc(sizeof(Node));
    Node* tree1 = (Node*)malloc(sizeof(Node));
    tree0->val = 0;
    tree1->val = 1;
    build_tree(tree0, 3);
    build_tree(tree1, 3);
    print_tree(tree0, buffer, 0);
    print_tree(tree1, buffer, 0);
使用int*数组的递归解决方案

#define MAX_LENGTH 32
int number[MAX_LENGTH];
void int_buffer_rec(int n, int length) {
    if(n > 0) {
        number[length - n] = 0;
        int_buffer_rec(n - 1, length);
        number[length - n] = 1;
        int_buffer_rec(n - 1, length);
    }
    else {
        for(int i = 0; i < length; ++i) {
            printf("%u", number[i]);
        }
        printf("\n");
    }
}

让我们从设计递归函数的原型开始。希望从那以后一切都有意义。看看这段代码的非递归版本,您将需要相同的变量。您不需要将它们中的任何一个作为参数传递,但我更愿意将它们全部传递,并使解决方案尽可能灵活和模块化。也考虑回报价值。为了模仿与C标准库的一致性,这可能意味着某种成功

int count_r(char *destination, /* The storage for the function to store *
                                *     the 0s and 1s as we count.        */
            size_t length,     /* The number of digits in the number.   */
            char *digit);      /* The set of digits                     */

现在让我们专注于设计第一次迭代。就像在小学一样,我们从定义我们的
count\r
开始,一次只迭代单个数字。一旦我们能够证明它知道如何从
0
计数到
9
,我们就把它引入两位数。。。但现在,一步一个脚印

假设在第一次调用之前,
目的地
被初始化为包含
长度
字节的
数字[0]
。这种初始化是由调用者完成的,调用者可能会在调用之前输出预先初始化的数组。第一次迭代应该只修改一个字节:由
length
指示的字节,然后返回给调用者

int count_r(char *destination, size_t length, char *digit) {
    /* The position of the right-most digit is before the '\0' in destination, *
     *     so we need to decrement length                                      */
    length--;

    /* Find the digit at the very end of destination, within our "digit" parameter */
    char *d = strchr(digit, destination[length]);

    /* d[1] points to the next digit (or '\0') */
    destination[length] = d[1];
    return 0;
}
然后调用者可能打印数组,并使用相同的缓冲区再次调用
count\r
,以增加计数器。这适用于不同的基,通过反转
数字
字符串,我们可以减少而不是增加。但是,正如我们很快就会看到的,当它达到可以计数到的最大值时,它会失败:
'F'
,在下面的示例中

int main(void) {
    char num[] = "0";
    do {
        puts(num);
    } while (count_r(num, strlen(num), "0123456789ABCDEF") == 0);
}

当计数更高时,d[1]将是
'\0'
,因为它将迭代超过数字集并进入字符串的空终止符。让我们考虑添加代码来处理第二次迭代。< /P> 需要一位代码才能将
目的地[长度]
设置回第一位
数字
,并递归地向左移动到下一位。这发生在
d[1]='\0'
时,因此我们可以编写
if(…){…}
分支来处理这个问题

length
作为0传入时会出现一个问题,我们在实现刚才提到的更改后会发现这个问题。函数应在此处返回
1
,以指示计数已完成,因为它已尽可能向左移动并达到了可能高的数字

void count_r(char *destination, size_t length, char *digit) {
    /* The position of the right-most digit is before the '\0' in destination, *
     *     so we need to decrement length                                      */
    if (length-- == 0) { return 1; }

    /* Find the digit at the very end of destination, within our "digit" parameter */
    char *d = strchr(digit, destination[length]);

    /* d[1] points to the next digit (or '\0') */
    if (d[1] == '\0') {
        /* Set destination[length] to the first digit */
        destination[length] = digit[0];
        /* Recurse onto the next digit. We've already decremented length */
        return count_r(destination, length, digit);
    }

    destination[length] = d[1];
    return 0;
}

在添加了一些
assert
离子(例如
assert(strlen(digit)>1);
)并编写了一些测试用例之后,我们可能会确定该函数已经准备好用于生产。我希望我能帮上忙。:)

我试图将我的解决方案限制为使用相同的参数,但我最终会添加一个额外的参数以了解count的初始值

void rec(int val, int count) {
    if (count <= 1) {
        int i;
        int f = 0;
        for (i = sizeof(int) * 8; i >= 0; i--) {
            f |= (val >> i) & 1;
            if (f) {
                printf("%d", (val >> i) & 1);
            }
        }
        printf("\n");
    } else {
        rec(val * 2, count - 1);
        rec(val * 2 + 1, count - 1);
    }
}
为了添加前导0,我添加了一个参数:

#include <stdio.h>

void rec2(int val, int count, int b) {
    if (count <= 1) {
        int i;
        for (i = b - 1; i >= 0; i--) {
            printf("%d", (val >> i) & 1);
        }
        printf("\n");
    } else {
        rec2(val * 2, count - 1, b);
        rec2(val * 2 + 1, count - 1, b);
    }
}

void rec(int val, int count) {
    rec2(val, count, count);
}

int main() {
    rec(0, 4);
    rec(1, 4);
    return 0;
}

解决方案1:更一般化的答案(可在c90、c99下编译)。布尔值输出为int。 限制:
1) 使用数学库。(它比较重。)


递归是一种编程技术,允许程序员用自己的方式来表达操作。在C++和C++中,这需要调用一个函数的形式,称为自身< /强> .<
#include<iostream>
#include<cstdio>
using namespace std;
void rec(int val)
{
  if(val<16)
  {
    printf("%u%u%u%u", val>>3, (val&4)>>2, (val&2)>>1, val&1);
    printf("\n");
    rec(++val);    //calling val+1 here
  }
  return;
}
int main()
{
   rec(0);  //calling recursion for 0
}
#包括
#包括
使用名称空间std;
无效记录(内部值)
{
如果(val>3,(val&4)>>2,(val&2)>>1,val&1);
printf(“\n”);
rec(++val);//在这里调用val+1
}
返回;
}
int main()
{
rec(0);//调用0的递归
}
这将为您提供所需的精确输出

如果不想使用位移位运算符

#include<iostream>
#include<cstdio>
using namespace std;
void rec(int val)
{
   if(val<16)
   {
     for(int b=val,a=8,i=0;i<4;b%=a,a/=2,i++)
     printf("%u",(b/a));
     printf("\n");
     rec(++val);// calling val+1 here
   }
   return;
}

int main()
{
   rec(0);//calling recursion for 0
}
#包括
#包括
使用名称空间std;
无效记录(内部值)
{

if(val这个问题可以推广到使用递归获得任意长度的二进制组合。例如,如果您想获得
length=4
的所有二进制组合,只需调用
printbinarycomposition(“???”,0)
(即四个
需要替换为
0
1

相应代码如下:

void printBinaryCombination(string str, int current)
{
    int length = str.length();
    if (length == 0)
        return;

    if (current == length)
        printf("%s\n", str.c_str());
    else
    {
        if (str[current] == '?')
        {
            str[current] = '0';
            printBinaryCombination(str, current+1);

            str[current] = '1';
            printBinaryCombination(str, current+1);

            // change back for next time
            str[current] = '?';
        }
        else
            printBinaryCombination(str, current+1);
    }
}
编辑:实际上,上述函数还可以处理包含随机数的
的所有二进制组合,每个组合可以是
0
1
。例如,如果调用
PrintBinaryComposition(“1??0”,0)
,它将打印:

1000
1010
1100
1110

生成您要求的n位组合(您要求的n=4) 一般的
1000
1010
1100
1110
vector<string> ve,ve1;
int main(int argc, char const *argv[])
{
    /* code */
    int n;
    cin>>n;
    generate("0",n,true);
    generate("1",n,false);
    for(int i=0;i<ve.size();i++){
        cout<<ve[i]<<endl;
    }
    for(int i=0;i<ve1.size();i++){
        cout<<ve1[i]<<endl;
    }
    return 0;
}
void generate(string s,int n,bool b){
    if(n==1){
        if(b==true){
            ve.push_back(s);
        }
        else{
            ve1.push_back(s);
        }
        return;
    }else{
        generate(s+"0",n-1,b);
        generate(s+"1",n-1,b);
    }
}
const int num=3;
string code="";

void GenerateBinaryCode(string str,unsigned int n){
    if(n==0){
        cout<<str<<endl;
    }
    else{
        str[num-n]='0';
        GenerateBinaryCode(str,  n-1);
        str[num-n]='1';
        GenerateBinaryCode(str, n-1);
    }
}
int main(){
    for(int i=0; i<num; i++)
        code+="x";

    GenerateBinaryCode(code,num);

}
l1 = [0]
l2 = [ [1,1] , [1,0] ]
then 
f1(l1,l2) = [ [0,1,1] ,[0,1,0]]


    def f1(l1:List[Int],l2:List[List[Int]]): List[List[Int]] = l2.map{ r=> l1:::r}
l1 = [ [0] , [1]]
l2 = [ [1,0], [1,1] ]
f(l1,l2) = [ [0,1,0],[0,1,1], [1,1,0],[1,1,1] ]


    def f(l1:List[List[Int]],l2:List[List[Int]]): List[List[Int]] = l1.map{ r=> f1(r,l2)} flatten
/**
n : The max number of digits that the binary number can contain
*/

    def binaryNumbers(n:Int):List[List[Int]] = n match {
     case 1 => List(List(0),List(1))
     case _ => f( List(List(0),List(1)) , binaryNumbers(n-1) )
    }

Example: binaryNumbers(2) = List( List(0,0), List(0,1), List(1,0), List(1,1) )
static void btable(int* a, int i, int n, int k, size_t len) {
    if (k >= len)
        return;
    for (int j = (i+n)/2; j < n; j++)
        *(a+j*len+k) = 1;
    btable(a,i,(i+n)/2,k+1,len);
    btable(a,(i+n)/2,n,k+1,len);
}
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main(void) {

    int n = 4;
    int (*a)[n] = malloc(sizeof(int[(int)pow(2,n)][n]));
    btable(*a,0,pow(2,n),0,n);

    for (int i = 0; i < pow(2,n); i++) { // verify output
        for (int j = 0; j < n; j++)
            printf("%d",a[i][j]);
        printf("\n");
    }

    return 0;
}