日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

c語言?深入理解函數的遞歸_C 語言

作者:誠摯的喬治 ? 更新時間: 2022-04-15 編程語言

前言:

?首先,遞歸是什么,遞歸就是在定義函數時,然后在函數里調用這個函數,通俗講,就是函數自己調用自己。那么遞歸的好處是什么呢?它能夠將復雜的問題,用少量的代碼來表示,增加了代碼的可讀性。

但是遞歸有一個條件,就是每一次的重復調用都需要越接近這個限制條件。

1.用遞歸打印一個整數的每一位

題目的要求是打印一個整數的每一位,就比如說1234,打印的結果就是1234,我們學過用循環打印過4321,但順著打印,用循環來做,相對于遞歸來解,就會有點復雜。

#include<stdio.h>//打印一個整數的每一位,用遞歸
print(int n)
{
	int i = 0;
	if(n>9)
	{
		print(n / 10);
	}
	printf("%d", n%10);
}
int main()
{
	int num = 0;
	printf("請輸入一個整數:");
	scanf("%d",&num);
	print(num);
	return 0;
}

這道題就是利用了遞歸的思想,此時的遞歸函數就是print函數。

首先是遞歸中的“遞”

當我們在scanf函數中輸入一個整數1234時,第一次進入print函數里,通過if語句再次進入print函數里,注意這時還未進行printf打印出結果。

這就到了第二次進入print函數里,此時進入函數的數子不在時?1234,而是除以十后的123,進入print函數后,再次通過if語句,進入print函數,注意這時也還未進行printf打印出結果。

第三次進入print函數里,是除以十后的12,12依然大于9,所以再次通過if語句,進入print函數,這時進入print函數的是除以十后的1.注意這時也還未進行printf打印出結果

第四次調用print函數時,此時的n就是1,顯然不滿足大于9的條件。這時的1余以十的結果還是1,于是首先打印出1。

然后就是遞歸中的“歸”

打印完1后,第四次進入循環的過程就結束了,此時,接著歸回上一次的循環,我們知道上次的循環到進入if語句后,就沒有再次往下進行,歸時就接著上次的操作,往下進行運行,就打印12余十的結果2,同理,就打印出最終的1234.

2.遞歸求n的階乘

你是否還記得上次求n的階乘還是說在上次。這次用遞歸來求解n的階乘,實際上也是非常的簡單,先寫出不用遞歸來求n的循環。

#include<stdio.h>//求n的階乘
int main()
{
	int num = 0; int i = 0; int ret = 1;
	printf("請輸入一個值:");
	scanf("%d",&num);
	for (i = 2; i <=num; i++)
	{
		ret *= i;
	}
	printf("%d", ret);
	return 0;
}

然后就是遞歸求n的階乘:

#include<stdio.h>//求n的階乘
int fac(int n)
{
	if (n > 1)
		return n * fac(n - 1);
	else
		return 1;
}
int main()
{
	int ret = 0;
	int num = 0;
	printf("請輸入n的值:");
	scanf("%d", &num);
	ret=fac(num);
	printf("%d", ret);
	return 0;
}

這時的n就是輸入的值,fac(n-1)就重復調用此函數,又可以無限接近這個n大于1的這個條件。這就用到了遞歸的思想。我們知道求n的階乘,也可以表示成n乘以(n-1)的階乘。以此重復,n-1等于1時就停止。就達到求n的階乘的目的~~

3.用遞歸和非遞歸求字符串的長度

求字符串的長度,不就是strlen函數嗎?

但是,不用這個庫函數呢

我們依然可以用兩種方法進行求解。

首先用非遞歸來求字符串的長度,也就是用我們自己的my_strlen函數。

#include<stdio.h>//用非遞歸求字符串的長度
my_strlen(char *arr)
{
	int a = 0; int ret = 0;
	char c = *(arr+a);
	while(arr[a] != '\0')
	{
		a++;
		ret++;
		}
	return ret;
}
int main()
{
	int ret = 0;
	char arr[] = "abc";
	ret=my_strlen(arr);
 	printf("%d", ret);
	return 0;
}

遞歸如下:

#include<stdio.h>
my_strlen(char* arr)
{
	int i = 0;
	if (*arr == '\0')
		return 0;
	if (*arr != '\0')
		return 1 + my_strlen(arr + 1);
}
int main()
{
	int ret = 0;
	char arr[] = "abc";
	ret = my_strlen(arr);
	printf("%d", ret);
	return 0;
}

這道題的思路就是一個一個字符來數,知道\0來結束此程序,我們知道“abc”是由abc\0四個字符組成,而遞歸的思路就是先數出a這個字符然后再數b,直到\0結束。

4.輸入一個數求各位數之和

這題的意思就是求出一個整數個十百千位之和,比如1234結果為10;

#include<stdio.h>//輸入一個數求各位數之和
sum(int x)
{
	int ret = 0;
	if (x > 9)
	{
		return  x % 10 + sum(x / 10);
	}
	else
		return x;
}
int main()
{
	int num = 0;
	printf("請輸入一個數之和:");
	scanf("%d", &num);
	printf("%d",sum(num));
	return 0;
}

5.用遞歸求n的k次方

#include<stdio.h>//用遞歸求n的k次方
tmp(int x,int y)
{
	if (y <= 0)
	{
		return 1;
	}
	else
		return x * tmp(x, y - 1);
}
int main()
{
	int k = 0; int n = 0;
	printf("請輸入一個n和k:");
	scanf("%d %d",&n, &k);
	int ret=tmp(n,k);
	printf("%d", ret);
	return 0;
}

6.計算斐波那契數

#include<stdio.h>//計算斐波那契數
feibona(int n)
{
	
	if (n >= 3)
		return feibona(n - 1) + feibona(n - 2);
	else 1;
}
int main()
{
	int n = 0;
	printf("請輸入一個n:");
	scanf("%d", &n);
	int ret=feibona(n);
	printf("%d", ret);
	return 0;
}

斐波那契數就是1 1 2 3 5 8 13……前兩個數之和得到第三個數

這里給出不用遞歸的求解:

#include<stdio.h>//用非遞歸求斐波那契數\
int feibona(int N)
{
int i = 1;
int j = 1;
int sum = i + j;
for (i = 4; i <= N; i++)
{
	i = j;
	j = sum;
	sum = i + j;
}
return sum;
}
int main()
{
	printf("請輸入一個n:");
	scanf("%d",&n);
	int ret=feibona(n);
	printf("%d", ret);
	return 0;
}

結語:

以上這些都利用到了遞歸函數的求解方法,思想都是差不多的,如果你仔細琢磨,會發現遞歸的魅力,這些例題可以拿來復習,歡迎大家支持 點贊 收藏~~

原文鏈接:https://z-ming.blog.csdn.net/article/details/122133577

欄目分類
最近更新