超星高级语言程序设计实验作业 实验06 递归程序设计

超星高级语言程序设计实验作业

实验06 递归程序设计

注:以下内容仅供交流,代码都是本人自己写的,还请同学们先自己编写再进行交流。

1.排列组合

问题描述:编写程序求函数C(m,n)的值。
在这里插入图片描述

输入:从键盘随机输入一个自然数和一个非负整数,分别作为m和n的值(m≥n)。
输出:函数C(m,n)的值。
样例1:
输入:4 1
输出:4
样例2:
输入:6 2
输出:15

#include<stdio.h>
//递归函数部分
int math(int m,int n) {
	if (n < 0) return 0;
	else if (n == 0) return 1;
	else if (n == 1) return m;
	else if (m < 2 * n) return math(m, m - n);
	else if (m >= 2 * n) return math(m - 1, n - 1) + math(m - 1, n);
}
//主函数
int main() {
	int m, n;
	scanf_s("%d%d", &m, &n);
	printf("%d", math(m, n));
	return 0;
}

这个题挺简单,按公式来就行。

2.Hermite多项式

题目描述:编写程序,用递归方法求解Hermite 多项式值。Hermite 多项式定义如下。
GJBook3-10-03.jpg
输入:从键盘随机输入一个非负整数和一个实数,作为n和x的值。
输出:Hn(x)的值,精确到小数点后2位。
样例1:
输入:0 1.5
输出:1.00
样例2:
输入:2 2.4
输出:21.04

#include<stdio.h>
//多项式函数部分
double H(double x,int n) {
	if (n == 0) return 1;
	else if (n == 1) return 2 * x;
	else return 2 * x * H(x, n - 1) - 2 * (n - 1) * H(x, n - 2);
}
//主函数部分
int main() {
	int n;
	double x;
	scanf_s("%d%lf", &n, &x);
	printf("%.2lf", H(x, n));
	return 0;
}

按公式来就好😁

3.Ackerman函数

问题描述:编写程序,计算 Ackerman 函数值。Ackerman 函数定义如下
在这里插入图片描述

输入:从键盘随机输入两个非负整数,分别作为m和n的值。
输出:Ack(m, n)的值。
样例1:输入 2 3 输出 9
样例2:输入 3 2 输出 29
样例3:输入 0 3 输出 4

#include<stdio.h>
int Ack(int m,int n) {
	if (m == 0) return n + 1;
	if (n == 0) return Ack(m - 1, 1);
	if (m > 0 && n > 0)
	return Ack(m - 1, Ack(m, n - 1));
}
int main() {
	int n,m;
	scanf_s("%d%d", &m, &n);
	printf("%d", Ack(m, n));
	return 0;
}

还是按公式来,注意要看清公式。

4.最大公因数

题目描述:编写程序,用递归方法求解m、n最大公约数。对正整数u和v 可以采用欧几里德辗转相除算法求它们的最大公因数,具体过程如下:
u% v → r1
v % r1 → r2
r1% r2 → r3
r2 % r3 → r4
… …
rn-1% rn → rn+1=0
当余数rn+1=0时,计算过程结束,rn 为正整数u 、v的最大公因数。
输入:从键盘随机输入两个正整数m和n。输出:最大公因数。
样例1:
输入:12 15
输出:3
样例2:
输入:28 49
输出:7

#include<stdio.h>
int C(int u,int v) {
	int r;
	//返回情况,进入函数时因为上步中传入的为u%v故此时的u可能为零,则v即为所求
	if (u==0) return v;
	//使u一直是较大的数,减少取余运算次数
	if (u < v) {
		r = u; u = v; v = r;
	}
	//当未从上面返回时,说明辗转相除未结束 较大数%较小数与较小数一起再进入函数
	return C(u % v, v);
}
int main() {
	int n,m;
	scanf_s("%d%d", &m, &n);
	printf("%d", C(m, n));
	return 0;
}

5.顺序检索

题目描述:编写程序,用递归方法在整数组中进行顺序检索。
输入:
第一行输入一个正整数n(0<n≤100),表示数组的元素个数;
第二行依次输入n个整数,作为数组的元素;
第三行输入待检索的关键字。
输出:
如果数组中含有关键字,则输出其首次出现的位置(下标值较小的位置)否则输出NULL。

样例1:
输入:
8
0 2 3 4 5 9 10 8
3
输出:
2
样例2:
输入:
8
0 2 3 4 5 9 10 8
6
输出:
NULL

#include<stdio.h>
// 递归函数部分,p指向储存第二行数字的数组首地址,key关键字,n数组长度,i记录首次出现位置
int C(int*p,int key,int n,int i) {
	if (i == n) return -1;//当进入时i为n说明前n项未出现关键值,即无结果返回-1
	if (*(p + i) == key) return i;//出现时返回当前位置
	else return C(p, key, n, i + 1);//未出现时进行下一项的判断
}
int main() {
	int n,a[100],key,i;
	scanf_s("%d", &n);
	for ( i = 0; i < n; i++)
		scanf_s("%d", &a[i]);
	scanf_s("%d", &key);
	key = C(a, key, n, 0);//用key再储存返回值,若为-1说明未找到,其他情况key即为下标值
	if (key == -1) printf("NULL");
	else printf("%d",key);
	return 0;
}

6.最大元素

题目描述:编写程序,用递归方法求解长度为n的整型数组中最大元素值。
输入:第一行输入一个正整数n(0<n≤100),表示数组的元素个数;第二行依次输入n个整数,作为数组的元素。
输出:最大元素的值。
样例1:
输入:
10
9 8 7 6 5 4 3 2 1 0
输出:
9
样例2:
输入:
10
0 1 2 3 4 5 6 7 8 9
输出:
9

#include<stdio.h>
//递归函数部分,r用于储存最大值,i记录当前比较项数
int max(int*p,int n,int r,int i) {
	//当i=n时比较结束,返回r
	if (i == n) return r;
	//比较r与当前项大小,将较大值赋给r
	if (r < *(p + i)) r = *(p + i);
	return max(p, n, r, i + 1);
}
int main() {
	int n,a[100],i;
	scanf_s("%d", &n);
	for ( i = 0; i < n; i++)
	 scanf_s("%d", &a[i]);
	 //函数中传入数组首地址,数组中的项数,开始为r传入a[0]的值,为i传入0
	printf("%d", max(a, n, a[0], 0));
	return 0;
}

7.数组反序

题目描述:编写程序,用递归方法反序数组。
输入:第一行输入一个正整数n(0<n≤100),表示数组的元素个数;第二行依次输入n个整数,作为数组的元素。
输出:顺次输出逆序后数组中元素,元素间以一个西文空格间隔,最后一个元素后无字符。
样例1:
输入:
8
0 2 3 4 5 9 10 8
输出:
8 10 9 5 4 3 2 0

样例2:
输入:
5
0 2 3 3 5
输出:
5 3 3 2 0

#include<stdio.h>
//递归函数部分,用于交换数组中值实现逆序
//其中开始时n直接赋值元素数减一即最后一个元素的下标,i记录当前交换项
void L(int*p,int n,int i) {
	int r;
	//交换对应需要逆序交换项的值
	r = *(p + i);
	*(p + i) = *(p + n - i);
	*(p + n - i) = r;
	//当i为n/2时,逆序完成结束递归
	if (i == n/2) return;
	L(p, n, i + 1);
}
int main() {
	int n,a[100],i;
	scanf_s("%d", &n);
	for ( i = 0; i < n; i++)
		scanf_s("%d", &a[i]);
	//调用函数实现逆序,直接传递最后一个元素的下标值,便于交换时指针的计算
	L(a, n-1, 0);
	for (i = 0; i < n; i++) {
		printf("%d", a[i]);
		if (i != n - 1)printf(" ");
	}
	return 0;
}

8.截木条

题目描述:
给定一个长度为n的木条,将其在大致2/5的位置截断,得到2个长度仍为整数的木条;如果新得到的木条的长度仍旧超过规定长度k,将继续按照上述方法处理得到的木条,直到所有木条的长度都不大于k。
编写程序,用递归方法计算一个长度为n的木条,当规定长度为k时,其经过上述截断过程会得到多少根木条。其中:n、k均为正整数,n>10,k>3,且假设木条截断所得短木条长度四舍五入为正整数,长木条长度为总长减去短木条长度。
输入:顺次从键盘输入两个正整数n和k(n>10,k>3)。
输出:木条根数。
样例1:
输入: 20 4
输出: 7
样例2:
输入: 3 20
输出: 1

#include<stdio.h>
//定义i储存木条个数
int i=1;
//递归函数部分
void L(int n,int k) {
	int n1=0, n2=0;
	//当n比k大时将n分割,这时木条数加一
	if(n>k){
		n1 = n * 2 / 5;
		n2 = n - n1;
		i++;
	}
	if (n1 > k) L(n1, k);
	if (n2 > k) L(n2, k);
}
//主函数
int main() {
	int n,k;
	scanf_s("%d%d", &n,&k);
	if (n <= k);
	else L(n, k);
	printf("%d", i);
	return 0;
}

这个为了省事,直接用了全局变量😁
其他方法大家自行摸索吧

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值