test7_1222(递归实现斐波那契、n^k、DigitSum、字符串翻转、strlen、n!、打印一个整数的各个位)

1.递归和非递归分别实现求第n个斐波那契数。

打印斐波那契数列


void Fib(n) {
	int f1 = 1, f2 = 1;
	while(1) {
		printf("%d\t%d\t", f1, f2);
		f1 = f1 + f2;
		f2 = f1 + f2;

		Sleep(1000);
	}
}

循环实现:

int Fib(n) {
	int f1 = 1, f2 = 1;
	int i = 1;
	while (i < n/2.0) {
		
		f1 = f1 + f2;
		f2 = f1 + f2;
		i++;
	}
	if (n % 2 == 1)
		return f1;
	return f2;
}
int main() {
	int n;
	printf("请输入第n个斐波那契数列的n值:");
	scanf("%d", &n);
	if (n < 0)
		printf("Error!");
	
	int result = Fib(n);
	printf("%d\n", result);
	
	system("pause");
	return 0;
}

  递归实现:

int Fibon(n) {
	if (n == 0)
		return 0;
	else if (n < 0)
		return -1;
	if (n > 2)
		return Fibon(n - 1) + Fibon(n - 2);
	return 1;
}

int main() {
	int n;
	printf("请输入第n个斐波那契数列的n值:");
	scanf("%d", &n);

	int result = Fibon(n);
	printf("%d\n", result);
	
	system("pause");
	return 0;
}

2.编写一个函数实现n^k,使用递归实现

int pow(int n, int k) {

	if (k == 0) {
		return 1;
	}

	return n * pow(n, k - 1);
}
int main() {
	int result = pow(3, 3);
	printf("%d\n", result);
	system("pause");
	return 0;
}

3. 写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和
例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19

int sum = 0;

int DigitSum(int n) {
	
	if (n > 9) {
		DigitSum(n / 10);
	}
	printf("%d ", n % 10);

	sum += (n % 10);
	return sum;
}

int main() {
	
	int result = DigitSum(1729);
	printf("\nresult = %d\n", result);
	system("pause");
	return 0;
}

       在将每一位的数字取出来求和的时候,不论是将sum放在递归函数的哪个部分都会将sum的值出问题。然后想到了全局变量,刚好每次都能累加。
4. 编写一个函数 reverse_string(char * string)(递归实现)
实现:将参数字符串中的字符反向排列。
要求:不能使用C函数库中的字符串操作函数。

void swap(char* x, char* y) {
	char temp = *x;
	*x = *y;
	*y = temp;
}

void reverse_string(char string[],
	char* left, char* right) {

	if (left <= right) {
		swap(left, right);
		reverse_string(string, left + 1, right - 1);
	}
}

int main() {
         //定义1024个长度,防止数组长度溢出
	char arr[1024] = "";
	
	printf("请输入一段字符串:");
	scanf("%s", &arr);

	char* left = arr;
	char* right = arr + strlen(arr) - 1;
	
	reverse_string(arr, left, right);

	//输出数组:

	printf("%s\n", arr);

	system("pause");
	return 0;
}

    在解决问题的时候,因为没搞清楚函数实参和形参的传递。函数基础打得不是很牢靠,要对函数的传参加深理解记忆。

       在实现的时候,尝试手动输入一段字符串,发现这样子输入的数组并不是一个以“\0”结尾的c风格字符串,出现了数组周围的堆栈被破坏的情况。查阅资料得到,strlen()函数只能求以“\0”结尾的c风格字符串的长度。

      ps:scanf函数手动输入的就是一个c风格的字符串!

        最后,求教了老师。发现,当定义数组变量时: int arr[] = ""; 已经给arr分配了长度为1个元素 ‘\0’ 的内存。后面,scanf函数手动输入字符串的时候,就会产生数组越界,最终使用递归的时候,就导致arr周围的堆栈被损坏!

void rev(const char* string) {
	
	if (*string == '\0') {
		return;
	}
	rev(string + 1);
	printf("%c", *string);   递归出来的时候,依次从后往前打印单个字符
}


5.递归和非递归分别实现strlen

非递归实现

int len(char* p) {
	int count = 0;
	while (*p != '\0') {
		count++;
		p = p + 1;
	}
	return count;
}
int main() {
	char arr[] = "abc";
	printf("%d\n", len(arr));
	
	system("pause");
	return 0;
}

递归实现

1.用count做参数传递(可以使用计数变量传参,解决问题)


int length(char* p, int count) {

	if (*p == '\0') {
		
		return count;
	}
	length(p + 1, ++count);
}

int main() {
	char arr[] = "hello";
	int count = 0;
	char* p = arr;

	int result = length(arr, count);
	printf("%s 的长度为:%d\n", arr, result);
	system("pause");
	return 0;
}

2.定义全局变量count


int count = 0;
int length(char* p) {

	if (*p != '\0') {
		count++;
		length(p + 1);
	}
	return count;
}

int main() {
	char arr[] = "hello";

	int result = length(arr);
	printf("%s 的长度为:%d\n", arr, result);
	system("pause");
	return 0;
}

6.递归和非递归分别实现求n的阶乘

int fac(int n) {
	if (n == 1) {
		return 1;
	}
	return n * fac(n-1);
}
int main() {
	int n;
	printf("输入一个需要计算的数:");
	scanf("%d", &n);

	printf("n!=%d", fac(n));
	system("pause");
	return 0;
}
int fac(int n) {
	if (n == 1) {
		return 1;
	}
	return n * fac(n-1);
}
int main() {
	int n;
	printf("输入一个需要计算的数:");
	scanf("%d", &n);

	printf("n!=%d", fac(n));
	system("pause");
	return 0;
}

7.递归方式实现打印一个整数的每一位

void print(int num) {
	if (num > 9)
		print(num / 10);
	printf("%d、", num % 10);
}
int main() {

	int num ;
	printf("输入要打印的数:");
	scanf("%d", &num);
	print(num);

	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Q_feifeiyu/article/details/85728634