【C语言】习题①接收一个整型值|习题②模拟实现字符串函数|习题③求斐波那契数

举报
謓泽 发表于 2023/09/28 17:03:04 2023/09/28
【摘要】 【C语言】递归两个必要条件|习题①接收一个整型值|习题②模拟实现字符串函数|习题③求斐波那契数

🔥习题①→接收一个整型值(无符号),顺序打印出每一位。例如 1234,输出 1 2 3 4!

解题思路🖊

  • 1234 % 10 = 4
  • 1234 / 10 = 123    123 % 10 = 3
  • 123 / 10 = 12        12 % 10 = 2
  • 12 / 10 = 1            1   % 10 = 1

%u → 无符号10进制整数。

最后:1 / 10 = 0,当我这个数为 0 的时候,就得到了所有输出的数字。但是你会发现,我们这里得到数字都是倒着打印的,当然用数组也可以实现正向打印。不过麻烦,所以我们这里带大家实现用递归如何输出上述程序!

注意:当函数递归完之后是会继续再次从递归的函数开始执行,直到你满足限制条件!

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void print(unsigned int number)
{
	if (number > 9)             //限制条件
	{
		print(number/10);       //调用这个函数,直到表达式为假 执行下面语句
	}
	printf("%d ", number % 10);
}
int main(void)
{
	unsigned int number = 0;
	printf("请输入数字:");
	scanf("%u", &number);

	print(number);

	return 0;
}

简单说明:栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

拓展,栈:当你递归调用的次数多了,那么每一次都要开辟一次内存空间,当开辟到空间存储不够的时候,那么就会发生栈溢出的情况!所以我们在写递归的时候需要注意下:

  1. 绝对不能够进行死递归,死递归就必然栈溢出。因为,它没有跳出这个循环。
  2. 递归每次就必须要逼近这个跳出条件。
  3. 递归不能够"太深",也就是层次不能太深。这样也会有栈溢出。

🔥习题②→模拟实现字符串函数,用递归的形式,不能创建临时变量。

解题思路🖊

这个题目是求字符串长度,那我们要求一个字符串函数,不就是模拟strlen吗?就是实现这个字符串函数的功能,让我们自己创建一个自定义函数来去实现。

  • 用 My_strlen 求字符串函数!那么字符串就是:
  • My_strlen("Cnb");的长度!形参字符型指针变量str指向的不就是这个字符串吗。那么这个拿到字符串的第一个长度是很容易的,因为我们一开始str就是从第一个字符拿到的不是吗?刚好可以进行判断它是不是'\0',如果不是就继续执行!
  • 1+My_strlen("nb");就可以变成这种形式。这不就是上面的长度吗?因为我发现我的第一个字符串长度并不是'0',所以就可以变成这种形式。
  • 1+1+My_strlen("b");
  • 1+1+1My_strlen("");     在往后就是'\0'。最终结果运行结果为→3

代码示例如下↓

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int My_strlen(char *str)
{
	if (*str != '\0')
		return 1 + My_strlen(1 + str);
	else
		return 0;
}
int main(void)
{
	char arr[20] = {0};
	printf("请输入字符:");
	scanf("%s", &arr);

	printf("str = %d\n", My_strlen(arr));

	return 0;
}

🖊运行结果↓

请输入字符:123456

str = 6


🔥习题③→求斐波那契数!

  • 这个数列从第3项开始,每一项都等于前两项之和,这就是斐波那契数。
  • 公式:F(n - 1)+F(n - 2)、
  • 注意:这个代码不适合用递归,如果你输入的数字是50以上的话就要递归好久层次太深,所以不适合用递归,递归固然有好处但是也要分场合使用。程序效率低下!

代码示例如下↓

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Fib(n)
{
	int a = 1;
	int b = 1;
	int c = 1;
	int count = 0;	//计数
	while (n > 2)
	{
		c = a + b; // 1 1 2 3 5 8 13 21 34 55
		a = b;     // 1 2 3 4 5 6 7  8  9  10
		b = c;      
		n--;
		count = count + 1;
	}
	printf("count = %d\n", count);
	return c;
}
int main(void)
{
	int n = 0;
	printf("请输入数字:");
	scanf("%d", &n);
	int c = Fib(n);
	printf("c = %d\n", c);
	
	return 0;
}

那么这里我再把递归的代码给大家看看!来用递归的形式做斐波那契数列,大家可以看下区别,但是如上所说这里使用递归做不合适。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Fib(int n)
{
	if (n <= 2)
		return 1;
	else
		return Fib(n - 1) + Fib(n - 2);
}
int main(void)
{
	int n = 0;
	printf("请输入数字:");
	scanf("%d", &n);
	int ret = Fib(n);
	printf("ret = %d\n", ret);

	return 0;
}

那么这里我们需要知道为什么用递归的方法不合适做斐波那契数列。

从上面的代码可以看出用递归的方法代码比前面的方法简短了不少,直接将斐波那契数列的递推公式带入即可实现。但是,用递归实现的话会有一个非常大的缺点:效率低下(算法的运行速度比较慢),尤其是当我们输入的n较大时。那么程序计算的时候需要的时间很长,这是因为程序在每次递归调用自己时都需要算一遍(n-1)和(n-2)项,存在很多重复计算。不考虑栈溢出的情况。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。