1)、和算法关系最紧密的是数据结构。
2)、算法:一种有限、确定、有效的并适合用计算机程序来实现的解决问题的方法。算法是计算机科学的基础,是这个领域研究的核心。
3)、欧几里德算法又称辗转相除法,是指用于计算两个正整数a、b的最大公约数
4)、用某种特定语言写出一段程序只是表达一个算法得一种方法。
5)、学习算法的主要原因是它们能节约非常多的资源,甚至能够让我们完成一些本不可能完成的任务 。 在某些需要处理上百万个对象的应用程序中,设计优良的算法甚至可以将程序运行的速度提高数百万倍 。 与此相反,花费金钱和时间去购置新的硬件可能只能将速度提高十倍或是百倍 。 无论在任何应用领域,精心设计的算法都是解决大型问题最有效的方法 。
一段 Java 程序(类)或者是一个静态方法(函数)库,或者定义了一个数据类型 。 要创建静态方法库和定义数据类型,会用到下面七种语法 ,它们是 Java语言的基础, 也是大多数现代语言所共有的 。
✦ 原始数据类型 : 它们在计算机程序中精确地定义整数、浮点数和布尔值等 。 它们的定义包括取值范围和能够对相应的值进行的操作,它们能够被组合为类似于数学公式定义的表达式 。
✦ 语句:语句通过创建交量并对其赋值、控制运行流程或者引发副作用来进行计算 。 会使用六种语句:声明 、赋值 、条件、循环 、 调用和返回 。
✦ 数组 : 数组是多个同种数据类型的值的集合 。
✦ 静态方法 : 静态方法可以封装并重用代码,使我们可以用独立的模块开发程序 。
✦ 字符串: 字符串是一连串的字符,Java 内置了对它们的一些操作 。
✦ 标准输入/输出: 标准输入输出 是程序与外界联系的桥梁 。
✦ 数据抽象: 数据抽象封装和重用代码,使我们可以定义非原始数据类型,进而支持面向对象编程。
数据类型就是一组数据和对其所能进行的操作的集合。Java语言最基本的原始数据类型:
✦ 整型,及其算术运算符( int ) ;
✦ 双精度实数类型,及其算术运算符( double );
✦ 布尔型,它的值 { true,false } 及其逻辑操作( boolean ) ;
✦ 字符型,它的值是你能够输入的英文字母数字字符和符号( char)。
Java 程序控制的是用标识符命名的变量 。 每个变量都有自己的类型并存储了一个合法的值 。 在Java 代码中 ,我们用类似数学表达式的表达式来实现对各种类型的操作 。 对于原始类型来说,我们用标识符:来引用变量 ,用+ 、- 、、/等运算符来指定操作,用字面量,例如 1 或者 3. 14 来表示值,用形如( x +2.236) / 2 的表达式来表示对值的操作 。 表达式的目的就是计算某种数据类型的值 。
Java程序的基本组成
只要能够指定值域和在此值域上的操作 ,就能定义 一个数据类型 。编程语言中的基本数据类型和它们都很相似 。 对于int 和 double 来说 ,这些操作是我们熟悉的算术运算;对于 boolean 来说则是逻辑运算 。 需要注意的重要一点是,+ 、、-、/都是被重载过的一一根据上下文,同样的运算符对不同类型会执行不同的操作 。 这些初级运算的关键性质是运算产生的数据的数据类型和参与运算的数据的数据类型是相同的 。 这也意味着我们经常需要处理近似值,因为很多情况下由表达式定义的准确值并非参与表达式运算的值。例如,5/3的值是 1 而 5.0 / 3. 0 的值是 1 .66666666666667 , 两者都很接近但并不准确地等于 5/3 。
Java中的原始数据类型
Java使用的是中缀表达式: 一个字面量(或是一个表达式),紧接着是一个运算符,再接着是另一个字面量(或者另一个表达式)。 当一个表达式包含一个以上 的运算符时,运算符的作用顺序非常重要, 因此 Java 语言规范约定 了如下的运算符优先级 : 运算符,【*】和【/】(以及% ) 的优先级高于 + 和-(优先级越高,越早运算),在逻辑运算符中,【!】 拥有最高优先级,之后是 【&&】,接下来是【|| 】。一般来说,相同优先级的运算符的运算顺序是从左至右 。 与在正常的算数表达式中一样,使用括号能够改变这些规则 。 因为不同语言中的优先级规则会有些许不同 , 我们在代码中会使用括号并用各种方法努力消除对优先级规则的依赖 。
如果不会损失信息,数值会被自动提升为高级的数据类型 。转换指的是在表达式中把类型名放在括号里将其后的值转换为括号 中的类型 。 例如,( int)3.7 的值是 3 而( double)3 的值是 3. 0 。 需要注意的是将浮点型转换为整型将会截断小数部分而非四舍五入,在复杂的表达式中的类型转换可能会很复杂,应该小心并尽量少使用类型转换,最好是在表达式中只使用同一类型的字面量和变量。
下列运算符能够比较相同数据类型的两个值并产生一个布尔值 :相等( == )、不等(!= )、小于 (<)、小于等 于 (<= )、大于(>)和大于等 于 (>= )。 这些运算符被称为混合类型运算符,因为它们的结果是布尔型, 而不是参与比较的数据类型 。 结果是布尔型的表达式被称为布尔表达式 。
Java 的 int 型能够表示 232个不同的值, 用一个字长 32 位的机器字即可表示(虽然现在的许多计算机有字长 64 位的机器字,但int 型仍然是 32 位)。 与此相似,double 型的标准规定为 64 位 。这些大小对于一般应用程序中使用的整数和实数已经足够了 。
Java 提供了其他五种原始数据类型 :
✦ 64 位整数,及其算术运算符( long) ;
✦ 16 位整数 ,及其算术运算柯: ( short);
✦ 16 位字符,及其算术运算符 ( char);
✦ 8 位整数,及其算术运算符( byte ) ;
✦ 3 2 位单精度实数,及其算术运算符 ( float ) 。
Java 程序是由语句组成的 。 语句能够通过创建和操作变量、对变量赋值并控制这些操作的执行流程来描述运算 。 语句通常会被组织成代码段,即花括号中的一系列语句 。
✦ 声明语句 :创建某种类型的变量并用标识符为其命名 。
✦ 赋值语句: 将(由表达式产生的)某种类型 的数值赋予一个变量 。Java 还有一些隐式赋值的语法可以使某个变量的值相对于当前值发生变化,例如将一个整型值加1 。
✦ 条件语句:能够简单地改变执行流程一一根据指定的条件执行两个代码段之一 。
✦ 循环语句: 更彻底地改变执行流程一一只要条件为真就不断地反复执行代码段中的语句 。
✦ 调用和返回语句:和静态方法有关,是改变执行流程和代码组织的另一种方式 。
程序就是由一系列声明、赋值、条件、循环、调用和返回语句组成的 。一般来说代码的结构都是嵌套的;一个条件语句或循环语句的代码段中也能包含条件语句或是循环语句 。
声明语句将一个变量名和一个类型在编译时关联起来 。Java 需要我们用声明语句指定变量的名称和类型 。Java 是一种强类型的语言 ,因为 Java编译器会检查类型的一致性(例如,它不会允许将布尔类型和浮点类型的变量相乘)。 变量可以声明在第一次使用之前的任何地方------一般我们都在首次使用该变量的时候声明它 。 变量的作用城就是定义它的地方, 一般由相同代码段中声明之后的所有语句组成 。
赋值语句将(由一个表达式定义的)某个数据类型的值和一个变量关联起来。赋值语句的左侧必须是单个变量,右侧可以是能够得到相应类型的值的任意表达式 。
有些情况下我们也会需要比基本的【if】和【while】语句更加复杂的流程控制 。 相应地 ,Java 支持在【 while 】循环中使用另外两条语句 :
✦ break 语句, 立即从循环中退出;
✦ continue 语句 ,立即开始下一轮循环 。
当希望一个变量的值相对于其当前值变化时,可以使用一些简便的写法 。
✦ 递增/递减运算符,【++i;】------>【i=i+1;】且表达式为i+1;
【- -i;】------>【i=i-1;】 使用变量i之前,先使i的值加(减)1
而【i++】(i- -)表示在使用变量i之后,使i的值加(减)1。
✦ 其他复合运算符,在赋值语句中将一个二元运算符写在等号之前,等价于左边的变量放在等号右边并作为第一个操作数。例如 ,【i/=2;】 等价于【 i=i / 2;】【i +=1】;等价于【i=i+1;】
很多循环的模式都是 : 初始化一个索引变量,然后使用 while 循环并将包含索引变量的表达式作为循环的条件,while 循环的最后一条语句会将索引变量加1。
在代码中使用数组时,一定要一次声明、创建并初始化数组。
✦ 在声明并创建数组之后,在代码的任何地方都能通过数组名之后的方括号中的索引来访问其中的元素。数组一经创建,它的大小就是固定的。程序能够通过a.length获取数组a[ ]的长度,而它的最后一个元素总是a[a.length-1]
典型的数组处理代码
// 找出数组中最大的元素
double[] a = new double[10];
double max = a[0];
for (int i = 1; i < a.length; i++) {
if (a[i] > max)
max = a[i];
}
// 计算数组元素的平均值
int N = a.length;
double sum = 0.0;
for (int i = 1; i < N; i++) {
sum += a[i];
double average = sum / N;
}
// 复制数组
int N = a.length;
double[] b = new double[10];
for (int i = 1; i < N; i++) {
b[i] = a[i];
}
// 颠倒数组元素的顺序
int N = a.length;
for (int i = 0; i < N / 2; i++) {
double temp = a[i];
a[i] = a[N - 1 - i];
a[N - i - 1] = temp;
}
// 矩阵相乘(方阵)a[][]*b[][]=c[][]
int N = a.length;
double[][] c = new double[10][10];
double[][] a = new double[10][10];
double[][] b = new double[10][10];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++) {
for (int k = 0; k < N; k++)
c[i][j] += a[i][k] * b[k][j];
}
在许多语言中,静态方法被称为函数,因为它们和数学函数的性质类似 。静态方法是一组在被调用时会被顺序执行的语句。
方法封装了由 一 系列语句所描述的运算 。 方法需要参数(某种数据类型的值)并根据参数计算出某种数据类型的返回值(例如数学函数的结果)或者产生某种副作用(例如打印 一个值)。
典型静态方法的实现
✦ 方法的参数按值传递:在方法中参数变量的使用方法和局部变量相同,唯一不同的是参数变量的初始值是由调用方提供的 。 方法处理的是参数的值,而非参数本身 。 这种方式产生的结果是在静态方法中改变一个参数变量的值对调用者没有影响 。
✦方法名可以被重载:重载的另一种常见用法是为函数定义两个版本,其中一个需要一个参数而另一个则为该参数提供一个默认值 。
✦方法只能返回一个值,但可以包含多个返回语句:一个 Java 方法只能返回一个值,它的类型是方法签名中声明的类型 。 静态方法第一次执行到一条返回语句时控制权将会回到调用代码中 。 尽管可能存在多条返回语句,任何静态方法每次都只会返回一个值,即被执行的第一条返回语句的参数 。
✦方法可以产生副作用: 方法的返回值可以是 void ,这表示该方法没有返回值 。 返回值为void的静态函数不需要明确的返回语句,方法的最后一条语句执行完毕后控制权将会返回给调用方 。 我们称 void 类型的静态方法会产生副作用(接受输入 、产生输出 、 修改数组或者改变系统状态)。
编写递归代码时最重要有一下的三点:
✦ 递归总有一个最简单的情况———方法的第一条语句总是一个包含return 的条件语句 。
✦ 递归调用总是去尝试解决一个规模更小的子问题,这样递归才能收敛到最简单的情况 。 在下
面的代码中,第四个参数和第三个参数的差值一直在缩小。
✦ 递归调用的父问题和尝试解决的子问题之间不应该有交集 。 在下面的代码中,两个子问题各自操作的数组部分是不同的 。
违背其中任意一条都可能得到错误的结果或是低效的代码,而坚持这些原则能写出清晰 、 正确且容易评估性能的程序 。 使用递归的另一个原因是可以使用数学模型来估计程序的性能 。
静态方法库是定义在一个 Java 类中的一组静态方法 。类的声明是public class 加上类名,以及用花括号包含的静态方法 。 存放类的文件的文件名和类名相同,扩展名是.java 。Java 开发的基本模式是编写一个静态方法库(包含一个 main()方法)来完成一个任务 。 输入 java 和类名以及一系列字符串就能调用类中的 main()方法,其参数为由输入的字符串组成的一个数组 。main () 的最后一条语句执行完毕之后程序终止。
字符串是由 一串字符( char 类型的值)组成的 。 一个String类型 的字面量包括一对双引号和其中的字符, 比如” Hello,World ” 。 String 类型是 Java 的一个数据类型,但并不是原始数据类型 。
字符串的两个主要用途分别是将用户从键盘输入的内容转换成相应数据类型的值以及将各种数据类型的值转化成能够在屏幕上显示的内容 。Java 的 Strng类型为这些操作内置了相应的方法,而且 Integer 和 Double 库还包含了分别和 String 类型相互转化的静态方法。
Java 在连接字符串的时候会自动将任意数据类型的值转换为字符串 : 如果加号( + )的一个参数是字符串,那么 Java 会自动将其他参数都转换为字符串(如果它们不是的话)。 除了像 ” The square root of 2. 0 is ”+ Math.sqrt(2.0〕这样的使用方式之外,这种机制也使我们能够通过一个空字符串" "将任意数据类型 的值转换为字符串值 。
在 Java 中字符串的一个重要的用途就是使程序能够接收到从命令行传递来的信息 。当输入命令 java 和一个库名以及一系列字符串之后 ,Java 系统会调用库的 main () 方法并将那一系列字符串变成一个数组作为参数传递给它 。
输入 、 输出和绘图库的作用是建立一个 Java 程序和外界交流的简易模型 。 在模型中,Java 程序可以从命令行参数或者一个名为标准输入流的抽象字符流中获得输入,并将输出写入另一个名为标准输出流的字符流中 。
默认情况下,命令行参数、标准输入和标准输出是和应用程序绑定的 ,而应用程序,是由能够接受命令输入的操作系统或是开发环境所支持 。 我们笼统地用终揣来指代这个应用程序提供的供输入和显示的窗口 。20 世纪 70 年代早期的 Unix 系统已经证明我们可以用这个模型方便直接地和程序以及数据进行交互 。
终端窗口包含一个提示哨,通过它我们能够向操作系统输入命令和参数 。 Java 类都会包含一个静态方法 main () ,它有一个 String 数组类型的参数 args [ ] 。 这个数组的内容就是我们输入的命令行参数 ,操作系统会将它传递给 Java。Java 和操作系统都默认参数为字符串 。如果我们需要的某个参数是数字,我们会使用类似 Integer.parseInt()的方法将其转换为适当的数据类型的值 。
一般来说,系统会将标准输出打印到终端窗口 。print()方法会将它的参数放到标准输出中;println() 方法会附加一个换行符;printf () 方法能够格式化输出。Java 在其 System .out 库中提供了类似的方法。
最常使用的转换代码包括d(用于Java整型的十进制数)、f(浮点型)、s(字符串)
它接受一个整数键和一个已经有序的int 数组作为参数 。 如果该键存在于数组中则返回它的索引, 否则返回 - 1。 算法使用两个变量 lo 和 hi, 并保证如果键在数组中则它一定在a [lo . . h i ] 中,然后方法进入一个循环,不断将数组的中间键(索引为 mid ) 和被查找的键比较 。如果被查找的键等于 a[mid ],返回 mid ; 否则算法就将查找范围缩小一半,如果被查找的键小于a [ m id ]就继续在左半边查找,如果被查找的键大于 a [mid ] 就继续在右半边查找 。 算法找到被查找的键或是查找范围为空时该过程结束。二分查找之所以快是因为它只需检查很少几个条目(相对于数组的大小)就能够找到目标元素(或者确认目标元素不存在)。
如果可能 ,我们的测试用例都会通过模拟实际情况来展示当前算法的必要性 。 这里该过程被称为 白名单过滤 。
具体来说, 可以想象一家信用卡公司 ,它需要检查客户的交易账号是否有效 。 为此,它需要:
✦ 将客户的账号保存在一个文件中,我们称它为白名单;
✦ 从标准输入中得到每笔交易 的账号;
✦ 使用这个测试用例在标准输出中打印所有与任何客户无关的账号,公司很可能拒绝此类交易 。
在一家有上百万客户 的大公司中,需要处理数百万甚至更多的交易都是很正常的 。