递归练习题_C语言实现

打印某个数的每一位

#include<stdio.h>
void print(unsigned int n)
{
	if (n > 9)
		print(n / 10);
	printf("%d ", n % 10);
}

int main()
{
	unsigned int num = 0;
	scanf("%u", &num);
	print(num);
	return 0;
}
//最简单的一种递归

求字符串长度

#include<stdio.h>
#include<string.h>
//编写函数,求字符串的长度。
int my_strlen(char* s)
{
	int count = 0;
	while(*s != '\0')
	{
		count++;
		s++;//就相当于地址加一,到了下一个字符 
		//这里跟下=下面不一样的是,我只需要能给s加到下一个地址就行,前自增后自增都一样,而下面那个的目的和这个不一样
	}
	return count;
}
int main()
{
	char arr[10] = "abcdef";//斜杠0之前出现了六个字符 之后还有三个默认的0
	int len = my_strlen(arr);
	printf("%d", len);//6
	return 0;
}
#include<stdio.h>
//如果上一题不允许创建临时变量(count)呢?(函数尽量不要全局变量),虽然形参也算临时变量,但是根据题意
//用递归解决 大事化小
int my_strlen(char* s)//这里也可以写成 char s[],语法上没错误
{
	if (*s != '\0')
		return 1 + my_strlen(s+1);//注意这里可以写++s,s+1,但不可以是s++,s++每次都给的是s,会死递归。
	else
		return 0;//一上来就是‘0’,空的
}
//my_strlen("abcd")-->1+my_strlen("bcd")-->1+1+my_strlen("cd")-->1+1+1+my_strlen("d")-->1+1+1+1+my_strlen(" ")-->1+1+1+1+0=4
int main()
{
	char arr[10] = "abcdef";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

求n!

#include<stdio.h>
//求n的阶乘,不考虑溢出
int Fac1(int n)//老办法 循环(迭代)                                                                                                                          
{
	int i = 0;
	int ret = 1;
	for (i = 1; i <= n; i++)
	{
		ret *= i;
	}
	return ret;
}

int Fac2(int n)//递归
//当n<=1时,阶乘为1;否则Fac(n)=n*Fac(n-1)=....
{
	if (n <= 1)
		return 1;
	else
		return n * Fac2(n - 1);
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret1 = Fac1(n);
	int ret2 = Fac2(n);
	printf("%d ", ret1);
	printf("%d ", ret2);
	return 0;
}

求第n个斐波那契数

#include<stdio.h>
//求第n个斐波那契数(前两个数字之和等于第三个数字)1 1 2 3 5 8 13 21 34 55
//当n<=2时,Fib(n)=1;当n>2时,Fib(n)=Fib(n-1)+Fib(n-2)
int count = 0;//这里用个全局变量当计数器,来看看3被重复计算了几次
int Fib1(int n)//递归
{
	if (n == 3)
		count++;
	if (n <= 2)
		return 1;
	else
		return Fib1(n - 1) + Fib1(n - 2);
}
int Fib2(int n)//迭代(循环)
{
	int a = 1;
	int b = 1;
	int c = 1;//这里c必须是1,因为走到下面return c的时候,如果不进入循环,斐波那契数应该为1
	while (n > 2)//当n等于3时,需要换一次;当n等于4时,需要换两次.....
	{
		c = a + b;
		a = b;
		b = c;
		n--;//他控制交换的次数
	}
	return c;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret1 = Fib1(n);
	int ret2 = Fib2(n);
	printf("%d\n", ret1);
	printf("如果用递归,第三个斐波那契数被重复计算了%d次\n", count);//这个数非常大
	printf("第n个斐波那契数为:%d", ret2);
	return 0;
}
//但是假如说算第五十个,会耗时非常长,故这题不适合此方法
//因为50--49+48,49--47+48,48--46+47....里面有大量的重复的计算

将参数字符串中的字符反向排列

//方法一 非递归
#include<stdio.h>
#include<string.h>
//编写一个函数 reverse_string(char * string)(递归实现)实现:将参数字符串中的字符反向排列,不是逆序打印。
//要求:不能使用C函数库中的字符串操作函数。
void reverse_string1(char* s)//非递归第一种 利用指针
{
	int len = strlen(s);
	char* left = s;
	char* right = s + (len - 1);
	while (left <= right)
	{
		char temp = *left;
		*left = *right;
		*right = temp;
		left++;
		right--;
	}
}
void reverse_string2(char* s)//非递归第二种 把形参看做数组名
{
	int len = strlen(s);
	int left = 0;
	int right = len - 1;
	while (left < right)
	{
		int temp = s[left];
		s[left] = s[right];
		s[right] = temp;
		left++;
		right--;
	}
}
int main()
{
	char arr1[20] = "abcdef";
	char arr2[20] = "qwer";
	//注意不能写成char* arr = "abcdef";
	//因为这样arr属于一个常量字符串,他是不能被改变的
	//曾经说过这种最好写成const char* arr = "abcdef"
	reverse_string1(arr1);
	reverse_string2(arr2);
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	return 0;
}
//方法二 递归(而且不用strlen函数)
#include<stdio.h>
//不准使用库函数
int my_strlen(char* s)
{
	if (*s != '\0')
		return 1 + my_strlen(s + 1);
	else
		return 0;//一上来就是‘0’,空的
}
void reverse_string(char* s)//或者传char s[]
{
	int len = my_strlen(s);
	char temp = s[0];//或者*s   a进入了temp
	s[0] = s[len-1];//f到了a的位置,但a还在temp
	s[len - 1] = '\0';//先给原来f的位置放个'\0',我写代码的时候出粗找了半天竟然是因为写成了/0
	if (my_strlen(s+1) >= 2)
		reverse_string(s + 1);//这个函数它能看见的范围就是 bcde(\0)
	s[len - 1] = temp;//再把a放到f的位置,但注意a已经是在temp里面了
}
//reverse("abcdef")-->交换af+reverse("bcde")-->交换af+交换be+reverse("cd")-->交换af+交换be+交换cd-->reverse(" ")
//具体实现的时候,要手动添加\0。比如交换完af之后,应该要先在e后面加个\0,然后再逆序bcde,然后再把a放在最后
int main()
{
	char arr[20] = "abcdef";
	reverse_string(arr);
	printf("%s\n", arr);
	return 0;
}

六进制转化

#include<stdio.h>
//六进制转换
void senary(int n)
{
    if (n >= 6)
        senary(n / 6);
    printf("%d", n % 6);//这句话和上句话不能交换位置,不然就错了,因为要从高位到低位打印
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    senary(n);
    return 0;
}
123/10=12···3
12/10=1·····2
1/10=0······1    
逆序上去就是123,这就是123的十进制,同理可以理解六进制或者其他进制的转化
//非递归
#include<stdio.h>
int main()
{
	int num = 0;
	scanf("%d",&num);
	int i = 0;
	int j = 0;
	int arr[50] = { 0 };
	while (num)
	{
		arr[i] = num % 6;
		i++;
		num /= 6;
	}
	//i出来的时候多加了一次
	for (j = i-1; j >= 0; j--)//不实用j的话,for里可以写(i--;i>=0;i--)
	{
		printf("%d", arr[j]);
	}
	return 0;
}

计算一个非负整数的每位之和

#include<stdio.h>
//写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和
//例如,调用DigitSum(1729),则应该返回1 + 7 + 2 + 9,它的和是19
//输入:1729,输出:19
int Sum(int n)
{
	if (n > 9)
		return (n % 10) + Sum(n / 10);   
	else
		return n;
}
//Sum(1234)-->Sum(123)+4(1234%10)-->Sum(12)+3(123%10)+4(1234%10)-->Sum(1)+2+3+4-->1+2+3+4
int main()
{
	unsigned int n = 0;
	scanf("%d", &n);
	int ret = Sum(n);
	printf("%d", ret);
}

求n的k次方

#include<stdio.h>
double power(int n, int k)
{
	if (k == 0)
		return 1.0;
	if (k > 0)
		return n * power(n, k - 1);
	if(k<0)
		return 1.0 / power(n, -k);
}
//以上依次改成if==else if==else 逻辑也正确
//power(n,k)=n*power(n,k-1)
int main()
{
	int n = 0;
	int k = 0;
	printf("先输入基数,在输入次方数,中间用空格隔开\n");
	scanf("%d %d", &n, &k);
	double ret = power(n, k);
	printf("%lf\n", ret);
	return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值