对于这个数组,尝试这样的事情:
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;
}
使用递归方法的预期输出:
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
无法理解如何编写该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 ..
}
答案 0 :(得分:21)
最简单的解决方案:二进制转换,无递归
for(int i = 0; i < 16: ++i) {
printf("%u%u%u%u", i/8%2, i/4%2, i/2%2, i%2);
}
有关此循环的递归版本,请参阅MOHAMED's answer
以下解决方案使用的二进制递归
_ 000
_ 00 _/
/ \_ 001
0 _ 010
\_ 01 _/
\_ 011
_ 100
_ 10 _/
/ \_ 101
1 _ 110
\_ 11 _/
\_ 111
使用char*
缓冲区的递归解决方案,无二进制转换
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);
}
}
用法:
char number[5] = {0};
char_buffer_rec(number, 4);
仅使用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);
}
}
用法:
int_ten_rec(0, 1000);
此解决方案的另一个版本替换tenpower
width bitwidth
,使用可变填充替换printf width
,具体取决于length变量。 length
可以定义为新参数,程序常量等。
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);
}
}
用法:
int_rec(0, 4);
树解决方案,使用char*
缓冲区递归,无二进制转换
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 buffer[5] = {0};
Node* tree = (Node*)malloc(sizeof(Node));
tree->val = 0;
build_tree(tree, 4);
print_tree(tree, buffer, 0);
但是这会在每一行的开头打印一个额外的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 * array的递归解决方案
#define MAX_LENGTH 32
int number[MAX_LENGTH];
void int_buffer_rec(int n, int length) {
if(n > 0) {
number[4-n] = 0;
int_buffer_rec(n - 1, length);
number[4-n] = 1;
int_buffer_rec(n - 1, length);
}
else {
for(int i = 0; i < length; ++i) {
printf("%u", number[i]);
}
printf("\n");
}
}
用法:
int_buffer_rec(4, 4);
答案 1 :(得分:5)
递归可以使用+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
答案 2 :(得分:2)
只需遍历DFS深度为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);
}
答案 3 :(得分:2)
我试图将我的解决方案限制为使用相同的参数,但我肯定会添加一个额外的参数来了解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);
}
}
输出:
1
10
11
100
101
110
111
1000
1001
1010
1011
1100
1101
1110
1111
为了添加前导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;
}
输出:
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
答案 4 :(得分:1)
让我们从设计递归函数的原型开始。希望它从那里开始有意义。看一下这段代码的非递归版本,你需要相同的变量。您不需要将任何作为参数传递,但我更愿意将它们全部传递,并使解决方案尽可能灵活和模块化。考虑返回值。这应该表明某种成功,以模仿与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
,我们就会将其引入两位数...但是现在,一次一步。
我们假设在第一次调用之前,destination
被初始化为包含length
字节的digits[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
来增加计数器。这适用于不同的基础,通过反转digit
字符串,我们可以递减而不是递增。但是,正如我们很快就会看到的那样,它在达到可以计入的最高数字后失败:'F'
在下面的示例中。
int main(void) {
char num[] = "0";
do {
puts(num);
} while (count_r(num, strlen(num), "0123456789ABCDEF") == 0);
}
当计时更高时,d [1]将为'\0'
,因为它将迭代超出数字集并进入字符串的空终止符。让我们考虑添加代码来处理我们的第二次迭代。
需要一些代码将destination[length]
设置回第一个digit
并递归地向左移动到下一个数字。这发生在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);
)并编写一些测试用例之后,我们可能会决定此功能是否已准备好进行生产。我希望我能够提供帮助。 :)
答案 5 :(得分: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
}
这为您提供了您想要的确切输出..!
如果您不想使用位移运算符..
#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
}
答案 6 :(得分:1)
通过使用递归,可以推广此问题以获得任意长度的二进制组合。例如,如果您想获得length=4
的所有二进制组合,只需调用printBinaryCombination("????", 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}}。例如,如果您致电1
,则会打印:
printBinaryCombination("1??0", 0)
答案 7 :(得分:1)
要生成你要求的n位组合(你要求n = 4) 任何n的一般递归实现都是:
主要功能:
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);
}
}
希望这会有所帮助..
答案 8 :(得分:0)
SOLN 1:更广泛的答案(可在c90,c99下编译)。布尔值输出为int。
限制:
1)使用数学库。(它更重)。
#include<stdio.h>
#include<math.h>
#define MAXBITS 4
//#define MAXVALUES (((int)pow(2,maxb))-1)
const int MAXVALUES = (((int)pow(2,maxb))-1) //if this gives warning then use #define version.
void bin(int val,int total)
{
int i = 0;
if(val <= MAXVALUES) //can write pow(2,total-1)-1 but anyways..
{
for(i =0 ; i < total;i++)
{
printf("%d",!!(val&(int)pow(2,total-i-1)));
}
printf("\n");
}
else return;
bin(val+1,total);
}
int main()
{
setbuf(stdout,NULL);
bin(0,MAXBITS);//4 bits
return 0;
}
Soln 2:这可以通过char打印来完成。没有班次操作员。
限制:
1)它可以(正确)打印最多15(十进制)或0x0F(十六进制)值
2)共计
在堆栈上创建(5 * sizeof(char) * total) + (( total + 2) * (sizeof(int) + sizeof(int)))
(非常浪费)。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define MAXVALUES 15
#define MAXBITS 4
void bin(int val,int total) //@prototype void bin(int val);remove redundant total.
{
char *s = malloc(sizeof(char)*(total+1)); //cant declare variable array(atleast pre c99)
int i = 0;
if(val <= MAXVALUES )
{
for(i =0 ; i < total;i++)
{
s[total - i-1] = !!(val&(int)pow(2,i)) + '0';
}
s[total] = '\0';
printf("%s\n",s);
}
else return;
bin(val+1,total);
}
int main()
{
bin(0,MAXBITS);//4 bits
return 0;
}
答案 9 :(得分:0)
此通用 c ++ 代码适用于任意数量的位。只需将const int num更改为您想要生成二进制代码...
的任意位数
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);
}
答案 10 :(得分:0)
这是C语言中的递归实现,它仅使用int 2D数组(无字符串,字符或位移位)来获取任意位长。
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;
}
答案 11 :(得分:-1)
在提出最终解决方案之前,我将展示两个可用于实现目标的功能。
下一个功能的主要思想是将l1
列表的元素添加到l2
中包含的每个列表中。例如:
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}
第一个参数是一个列表,其中包含将添加到l2
列表中包含的每个数字列表的整数列表。例如:
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) )