1. 程式人生 > >No.19程式碼練習:斐波那契數列,某數k次冪,模擬實現strlen(),階乘 ,逆置字串(遞迴和非遞迴)

No.19程式碼練習:斐波那契數列,某數k次冪,模擬實現strlen(),階乘 ,逆置字串(遞迴和非遞迴)

學習不易,需要堅持。

遞迴

程式呼叫自身的程式設計技巧稱為遞迴( recursion)。遞迴做為一種演算法在程式設計語言中廣泛應用。 一個過程或函式在其定義或說明中有直接或間接呼叫自身的一種方法,它通常把一個大型複雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算,大大地減少了程式的程式碼量。遞迴的能力在於用有限的語句來定義物件的無限集合。一般來說,遞迴需要有邊界條件、遞迴前進段和遞迴返回段。當邊界條件不滿足時,遞迴前進;當邊界條件滿足時,遞迴返回。(來自百度百科)
巧用下幅圖幫助理解:
在這裡插入圖片描述
1.遞迴和非遞迴分別實現求第n個斐波那契數。

2.編寫一個函式實現n^k,使用遞迴實現
3. 寫一個遞迴函式DigitSum(n),輸入一個非負整數,返回組成它的數字之和,
例如,呼叫DigitSum(1729),則應該返回1+7+2+9,它的和是19

4.遞迴和非遞迴分別實現strlen
5.遞迴和非遞迴分別實現求n的階乘
6.
編寫一個函式 reverse_string(char * string)(遞迴與非遞迴實現)
實現:將引數字串中的字元反向排列。
要求:不能使用C函式庫中的字串操作函式。

1.
//遞迴和非遞迴分別實現求第n個斐波那契數並列印前40項

#include <stdio.h>

int fab1
(int n) { //非遞迴 int a = 1 ; int b = 1 ; int c = 0 ; if(n <= 2) { return 1 ; } else { int i = 1 ; for(i = 3; i<=n; i++) { c = a + b ; a = b ; b = c ; } } return c ; } int fab2( int n) { //遞迴 if(n <= 2) { return 1 ; } else { return fab2(n - 1) + fab2(n - 2
) ; } } void Fab() { int i = 0 ; int arr[40] = { 1, 1, 0 } ; for(i=2; i<40; i++) { arr[i] = arr[i-1] + arr[i-2] ; } for(i=0; i<40; i++) { printf("%10d ", arr[i]) ; if(0 == (i + 1) % 5) printf("\n") ; } printf("\n") ; } int main() { int m = 0 ; int order = 0 ; int ret1 = 0 ; //用來接收非遞迴求得的值 int ret2 = 0 ;// 用來接收遞迴求得的值 printf("----------此程式用來計算斐波那契數列----------\n") ; printf("\n請輸入你想要計算第幾個數列的值: ") ; scanf("%d", &order) ; ret1 = fab1(order) ; ret2 = fab2(order) ; printf("非遞迴求得第%d個斐波那契數列值為: %d\n", order, ret1) ; printf("遞迴求得第%d個斐波那契數列值為: %d\n", order, ret2) ; printf("\n----------將打印出前項斐波那契數列值----------\n") ; Fab() ; return 0 ; }

執行結果:

在這裡插入圖片描述

//編寫一個函式實現n^k,使用遞迴和非遞迴實現
#include <stdio.h>

int func1(int n, int k)
{
	//非遞迴
	int i = 1 ;
	int ret = 1 ;
	while(i <= k)
	{
		ret = ret * n ;
		i++ ;
	}

	return ret ;
}

int func2(int n, int k)
{
   //遞迴
	if(0 == k)
	{
		return 1 ;
	}

	else if(1 == k)
	{
		return n ;
	}

	else
	{
		return n * func2(n, k-1) ;
	}

	
}
int main()
{
	int n = 0 ;
	int k = 0 ;
	int ret1 = 0 ;
	int ret2 = 0 ;
	printf("----------此程式用來計算n的k次冪----------\n") ;
	printf("\n請給n和k賦值: ") ;
	scanf("%d%d", &n, &k) ;
	ret1 = func1(n, k) ;
	ret2 = func2(n, k) ;
	printf("\n非遞迴求得%d^%d = %d\n", n, k, ret1) ;
	printf("遞迴求得%d^%d = %d\n", n, k, ret2) ;
	printf("\n") ;
	return 0 ;
}

執行結果:
在這裡插入圖片描述

// 寫一個遞迴函式DigitSum(n),輸入一個非負整數,返回組成它的數字之和,
//例如,呼叫DigitSum(1729),則應該返回+7+2+9,它的和是

#include <stdio.h>

int DigitSum(int n)
{
	int m = 0 ;
	int sum = 0 ;
	if(n != 0)
	{
		m = n % 10 ;
		n = n / 10 ;
		sum= m + DigitSum(n) ;
	}
	return sum ;
}

int main()
{
	int n = 0 ;
	int ret = 0 ;
	printf("請輸入一個非負整數: ") ;
	scanf("%d", &n) ;
	ret = DigitSum(n) ;
	printf("各位和為%d\n", ret) ;
	return 0 ;
}

在這裡插入圖片描述

//用遞迴和非遞迴模擬實現strlen()函式

#include <stdio.h>

int My_strlen1(char* p)
{
//非遞迴
	int count = 0 ;
	 while(*p != '\0')
	 {
		 p++ ;
		 count++ ;
	 }
	 return count ;
}

int My_strlen2(char* str)
{
//遞迴
	if(*str != '\0')
		return 1+My_strlen2(str + 1) ;
	else
		return 0 ;
}

int main()
{
	int lenth1 = 0 ;
	int lenth2 = 0 ;
	char str[] = "Happy" ;
	lenth1 = My_strlen1(str) ;
	lenth2 = My_strlen2(str) ;
	printf("----------此程式用來模擬實現strlen()函式----------\n") ;
	printf(" 非遞迴求得\"Happy\" 長度為: %d\n", lenth1) ;
	printf(" 遞迴求得\"Happy\" 長度為: %d\n", lenth2) ;
	return 0 ;
}

執行結果:
在這裡插入圖片描述

//遞迴和非遞迴分別實現求n的階乘

#include <stdio.h>

int fun1(int n)
{
	//非遞迴
	int mul = 1 ; //儲存乘積
	while(n > 0)
	{
		mul = mul * n ;
		n-- ;
	}

	return mul ;
}

int fun2(int n)
{
   //遞迴
	if(n <= 1)
	{
		return 1 ;
	}
	else
	{
		return n * fun2(n - 1) ;
	}

}

int main()
{
	int n = 0 ;
	int ret1 = 0 ;
	int ret2 = 0 ;
	printf("----------此程式來計算n的階乘----------\n") ;
	printf("請輸入n的值: ") ;
	scanf("%d", &n) ;
	ret1 = fun1(n) ;
	ret2 = fun2(n) ;
	printf("非遞迴求得%d! = %d\n",n, ret1) ;
	printf("遞迴求得%d! = %d\n",n, ret2) ;
	return 0 ;
}

執行結果:
在這裡插入圖片描述

6.
//編寫一個函式 reverse_string(char * string)(遞迴與非遞迴實現)
//實現:將引數字串中的字元反向排列。
//要求:不能使用C函式庫中的字串操作函式。

#include <stdio.h>
#include <string.h>

int My_strlen(char* str)
{
	int lenth = 0 ;
	if(*str == '\0')
	{
		return 0 ;
	}
	while(*str != '\0')
	{
		str++ ;
		lenth++ ;
	}
	return lenth ;
}

void Reverse_string1(char* str)
{
	//非遞迴
	int left = 0 ;
	int right = My_strlen(str) - 1 ;
	while(left <= right)
	{
		char temp = str[left] ;
		str[left] = str[right] ;
		str[right] = temp ;
		left++ ;
		right-- ;
	}
}

void Reverse_string2(char* str)
{
	//遞迴
	char* p = str ;
	if(*p == '\0')
	{
		return ;
	}
	else
	{
		Reverse_string2(p+1) ;
		printf("%c", *p) ;
	}

}


int main()
{
	char str[] = "gfedcba" ;
	printf("----------此程式將字串逆轉----------\n") ;
	printf("逆轉前字串為: %s\n", str) ;
	printf("遞迴逆轉後字串為: ") ;
	Reverse_string2(str) ;
	printf("\n") ;
	Reverse_string1(str) ;
	printf("非遞迴逆轉後字串為: %s\n", str) ;
	printf("\n") ;
	return 0 ;
}

在這裡插入圖片描述

學習不易,需要堅持。