什么是函数?
函数是一段可以完成某个独立功能的代码
函数的本质是什么?
函数就是一个数据加工的黑箱子,我们不应该关注它内部实现的细节,而是关注它外部的信息,比如这个箱子是干什么的(功能),需要给它什么(参数)以及它可以得到什么结果(返回值)
对于程序员而言,更重要的是函数的设计,而不是实现
设计函数的三要素:
①函数名:见名思义,也就是根据功能定名字。
②参数:考虑实现这个功能,需要外部提供什么。
③预期结果(类型)如果函数正确执行,应该得到什么结果类型。
切记:函数设计只需要贵大三要素是什么,不能去考虑如何实现,或者说代码如何写。
为什么需要函数?
大事化小。也就是:将大的,复杂的问题分解为若干个小的,简单的问题去求解,能有效地帮助我们解决复杂的问题。
函数的作用:
1.避免冗余代码,提高程序的可维护性
2.提高代码的可重用性,函数库
3.提高代码的结构化,利与分工
案例:验证哥德巴赫猜想;任意一个大于六的偶数,都可以分解为两个素数之和。
案例:改进哥德巴赫猜想
private static int split(int n) {
for (int m=3;m<n/2;n+=2){//循环遍历所有奇数....m<n/2;eg:3+99/99+3,所以遍历到一半就可以。
if (isPrime(m) && isPrime(n - m)) {//如果m是素数,并且n-m也是素数
return m;//能够分解,返回其中之一,m或者n-m
}
}
return 0;//不能分解
}
将原来的判断能能否分解的函数改造成分解函数,其返回值表达的含义有两层:
①.能否分解 ②.怎么分
难题:return只能返回一个数,但是根据上面的要求需要返回三个数,怎么办?
/*
* 函数split中,要解决的是返回能不能分解,
* 和分解之后的两个素数是什么
*
* 因为最小的因子之和为1,所以当返回0的时候
* 表示不能分解
* 返回大于1的数表示能够分解的其中的一个数
* 用待分解的数去减去其中之一的数就能够得到
* 另外一个分解的数。
* */
有人可能提出在分解的函数中同时进行输出,如如下代码:
private static boolean canSplit(int n){
int i = 0;
for (int m = 3;m<n/2;m+=2){
if(isPrime(m)&&isPrime(n-m)){
System.out.printf("%d=%d+%d\n",n,m,n-m);
return true;
}
}
return false;
}
这种做法不好,理由:
①. 函数的功能要尽量单一,不能将多个功能揉在一起。
②. 如果在函数中直接进行输出,可能会导致这个函数的可重用性变差,比如你用中文输出,那外国程序员就没办法用你的函数了。
函数的参数和返回值参数:
调用函数时传给函数的数据
形式参数:
函数的声明中定义的变量,函数内部有效的局部变量。也就是说,在定义函数时给的参数叫做形式参数(形参),参数叫什么名字与功能无关,当然遵循见名思意的原则。
实际参数;
函数调用时传给形参的数据(实参)。
返回值:
函数返回时传回的数据,
函数的语法:
1.声明函数:static 返回值类型 函数名(参数表)
2.实现参数 {代码}
3.调用函数 函数名(参数表)
常见算法:
累加//累积
累加(累积)是我们经常用到的方法,比如我们之前做过的最简单的累加,求100以内的和就是累加,累加(累积)是将一系列数据的和(积)存入结果中。
累加形式:V=V+e+....;
累积形式:V=V*e*....;
V是累加(累积)的结果,e是递增表达式。我们的累加(累积)一般是通过循环结构来实现。
算法的要点:
①. 对循环的控制,比如我们求1-100以内的和,条件就是i<100
②. 递增表达式e的计算。
所以,这两个问题做到了,问题就能得到解决。
迭代:
迭代是一种不断用变量的新值迭代旧值的过程,使得新值不断的接近目标值。
1. 迭代变量:不断用新值代替旧值的变量,如迭代法求最大公约数中,被除数将除数迭代,除数被余数迭代。
2. 迭代条件的控制:迭代条件一般分为两种,一种是固定次数的迭代,另一种是次数无法确定,有一个结束迭代的条件。
穷举:
有时我们遇到问题,没有更好的解决方法的时候,也就是找不到更好的解决途径,就可以考虑我们这种 最“笨”的方法,即将所有可能的情况列举出来,然后通过逐个验证是否能解决问题。从而得到问题的解。
穷举的算法很简单,但往往计算量比较大,而计算机的优势在于,运算速度快,可以轻松的胜任这类问题的求解。
递推 递归