第20课 函数举例


前言

本课内容开启函数历练之旅。主要介绍了以下内容。

  • 进制转换
  • 计算组合数
  • 机器翻译
  • 维吉尼亚密码
  • 聪明的克鲁

一、主要内容

1. 进制转换

编程输入十进制数N(N: -32767~32767),请输出它对应的二进制、八进制、十六进制数。
分析:本题可以看作是将十进制数转换成R进制的数。算法是N除以R取余,再将所得各余数倒过来写出,即是转换后的R进制数,即“除R取余倒序”。
代码如下(示例):

#include<iostream>
using namespace std;
/*
编程将一个范围为(-32767,32767)内的十进制数n转换为二进制、八进制、十六进制数。
*/
void DecimalTo2816(int n, int r) {
	int data[20] = {0};
	int i = 0;
	if(n<0) {
		n = -n;
		cout << '-';
	}
	while(n!=0) {
		data[i++] = n%r;
		n /= r;
	}
	//倒序输出数组元素
	for(int j=i-1; j>=0; j--) {
		if (0<=data[j] && 9>=data[j]) cout << data[j];
		else if(10==data[j]) cout << 'A';
		else if(11==data[j]) cout << 'B';
		else if(12==data[j]) cout << 'C';
		else if(13==data[j]) cout << 'D';
		else if(14==data[j]) cout << 'E';
		else if(15==data[j]) cout << 'F';
	}
	cout << endl;
}

int main() {
	int num;
	cin >> num;
	DecimalTo2816(num, 2);
	DecimalTo2816(num, 8);
	DecimalTo2816(num, 16); 
	return 0;
}

下面位程序的一次运行测试:

-32767
-111111111111111
-77777
-7FFF

2. 计算组合数

一般第说,从n各不同的元素中取出m(m<=n)个元素组成一组,称为从n个不同元素中取出m个元素的一个组合。其中m个元素顺序无关。
从n个不同元素中取出m(m<=n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数,用符号C(n, m)表示。
C n m = n ! m ! × ( n − m ) ! \text C^m_n=\frac{n!}{m! \times (n-m)!} Cnm=m!×(nm)!n!

卡路的朋友聚会来了10位朋友,见面后每两人之间都要相互握手问候,请编程计算共需要握手多少次。
分析:总人数11人,这可以归为求从11个不同元素中取出2个元素的组合数。则总共握手的次数为:
C 2 11 = 11 ! 2 ! × ( 11 − 2 ) ! \text C^{11}_2 = \frac{11!}{2! \times (11-2)!} C211=2!×(112)!11!
程序中多次用到求阶乘,我们可以定义一个函数factor(n)来计算n!。

代码如下(示例):

#include<iostream>
using namespace std;

long long factorial(int n) {
	long long s=1;
	for(int i=1; i<=n; i++) {
		s *= i;
	}
	return s;
}

long long factor(int n) {
	if(n==0) return 1;
	else return n*factor(n-1);
}

int main() {
	int m=2, n=11;
	cout << factorial(n)/(factorial(n-m)*factorial(m)) << endl;
	cout << factor(n)/(factor(n-m)*factor(m)) << endl;
	return 0;
}


运行程序,输出结果为55。
有了计算阶乘的函数,如果要计算1!+2!+…+10!的结果就很方便了,我们只要修改main()函数如下即可。

int main() {
	long long sum=0, sum2=0;
	for(int i=1; i<=10; i++) {
		//cout << i << "\t" << factorial(i) << endl;
		sum += factorial(i);
		sum2 += factor(i);
	}
	cout << "sum=" << sum << endl;
	cout << "sum2=" << sum2 << endl;
	return 0;
}

课后练习

1. 冒泡排序

#include<iostream>
#include<iomanip>
using namespace std;

//冒泡排序法
void bubble_sort(int arr[], int size) {
	int temp = 0;
	bool swap_flag;
	//for循环中的内容是一趟冒泡排序,一共要进行sz-1趟
	//外层循环每循环一次就确定了一个相对最大元素
	for (int i = 0; i < size-1; i++) {
		swap_flag = false;
		for (int j = 0; j < size-1-i; j++) {
			//j<size-1-i,这里-i的原因是,我们已经排序好的元素不需要再参与到冒泡排序中
			//进行一次比较排序,将相邻的两个数进行比较
			//在第一次这里的for循环结束后,数组的最后一个元素就是数组中最大的数
			if (arr[j] > arr[j+1]) {
				temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
				if(!swap_flag) swap_flag =true;  //发生了交换操作
			}
		}
		if(!swap_flag) break;  //如果上一轮没有发生数据交换,证明已经是有序的了,结束排序
	}
}

int main() {
	int  a[] = {1, 5, 4, 11, 2, 20, 18};
	int len = sizeof(a)/sizeof(a[0]);
	for(int i=0; i<len; i++) {
    	cout << setw(5) << a[i];
	}
	cout << endl;
    bubble_sort(a, len);
    for(int i=0; i<len; i++) {
    	cout << setw(5) << a[i];
	}
	cout << endl;
	return 0;
}

运行程序,输出如下:
1 5 4 11 2 20 18
1 2 4 5 11 18 20

3. 计算两个数之差的绝对值

#include<iostream>

using namespace std;

int difference_abs(int a, int b) {
	if(a>=b) return a-b;
	else return b-a;
}

int main() {
	int x, y;
	cin >> x >> y;
	cout << difference_abs(x, y) << endl;
	return 0;
}

4. 寻找矩阵的最大元素

M 是一个3*3的整型矩阵,试编写一段程序,输入矩阵元素,输出其中最大元素。要求用 matrix_max(int M)函数实现求最大值功能。
已知matrix_max函数原型为: int matrix_max(int M[3][3]);
主函数调用语句为: max = matrix_max( m )。
输入:3行,每行3个整数,即矩阵元素,每行整数用空格分隔。
输出:1行,1个整数,即最大元素值。
样例输入:
1 2 3
9 8 7
4 5 6
样例输出:
9

#include<iostream>
#include<iomanip>
using namespace std;

int matrix_max(int A[3][3]) {
	int max=A[0][0];
	for(int i=0; i<3; i++) {
		for(int j=0; j<3; j++) {
			if(max<A[i][j]) max=A[i][j];
		}
	}
	return max;
}

void matrix_1(int A[], int m, int n) {
	int c=m*n;
	for(int i=0; i<c; i++) {
		cout << setw(4) << A[i];
		if((i+1)%m==0) cout << endl;
	}
}

int matrix_max2(int A[], int m, int n) {
	int c=m*n;
	int max=A[0];
	for(int i=0; i<c; i++) {
		if(A[i]>max) max=A[i];
	}
	return max;
}

int main() {
	int a[3][3];
	for(int i=0; i<3; i++) {
		for(int j=0; j<3; j++) {
			cin >> a[i][j];
		}
	}
	matrix_1(a[0], 3, 3);
	cout << matrix_max(a) << endl;
	cout << matrix_max2(a[0], 3, 3) << endl;
	cout << matrix_max2(&a[0][0], 3, 3) << endl;
	return 0;
}

运行程序,输入输出如下。
寻找矩阵的最大元素

5. 求斐波那契数列(Fibonacci sequence)的第20项

用函数递归的方式求斐波那契数列(Fibonacci sequence)的第20项。斐波那契数列数值为:1, 1, 2, 3, 5, 8, 13, 21, 34, …
问题数学函数式如下:
f ( n ) = {   1 n = 1 , 2   f ( n − 1 ) + f ( n − 2 ) n > 2 , n ∈ N f(n)= \begin{cases} \ 1 & n=1, 2 \\ \ f(n-1)+f(n-2) & n>2, \quad n∈N \end{cases} f(n)={ 1 f(n1)+f(n2)n=1,2n>2,nN

根据题目给出的数学函数式,可以很容易写出求斐波那契数列的第n项的递归函数。

#include<iostream>
using namespace std;

// 1,1,2,3,5,8,13,21,34,55,...
int fibonacci(int n) { 	
	int t1,t2; 	
	if(n==1 || n==2) 	{ 		
		return 1; 	
	} 	
	else { 		
		t1=fibonacci(n-1); 		
		t2=fibonacci(n-2); 		
		return t1+t2; 	
	} 	 
}

int fibo(int n) { 	
	if(n==1 || n==2) 	{ 		
		return 1; 	
	} 	
	else { 			
		return fibo(n-1)+fibo(n-2); 	
	} 	 
}

int main() {
	cout << fibo(10) << endl;	//55
	cout << fibo(20) << endl;	//6765
	return 0;
}

以上为暴力递归解法,代码虽然简洁,但是效率十分低下,算法的时间复杂度为O(2 n ),指数级别。
更多、更好的解法可以参阅CSDN博主「加班猿」的原创文章——“斐波那契数列”
原文链接:https://blog.csdn.net/m0_37824357/article/details/109711729

总结

函数是C/C++语言组织代码的重要的形式,在类中,类中函数就成为了类的成员方法。
在编写自定义函数时,考虑编写的函数的通用性是函数本身特性的内在要求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值