day05_排序与查找、正则表达式、异常
1. 冒泡排序、插入排序、二分查找
1.1 what、why、how
-
什么是算法?
- 算法就是解决某个实际问题的过程和方法
-
为什么要学算法?
-
面试会考 -
对于很多程序员来说,可能在工作中不会写出比冒泡排序更复杂的算法了,还有必要去花时间去学习吗?
**算法对计算机科学的所有分支都非常重要。**在绝大多数的计算机科学分支领域中,要想完成任何实质性的工作,理解算法的基础知识并掌握与算法密切相关的数据结构知识是必不可少的
-
学习算法可以让我们的编程思维更活跃,同时基础也更牢固,技术更牛x
-
-
怎样学习算法?
- 先想流程,再用代码实现
- 少年,你渴望力量吗
1.2 冒泡排序
- 什么是冒泡排序:
- 每次从数组中找出最大值放在数组的后面去
- 实现思路
- 依次进行比较,将较大元素往后移,从而进行排序,并循环进行
- 实现冒泡排序的步骤:
- 确定总共需要循环几次:数组长度-1
- 确定每轮需要比较几次:数组的长度-循环轮次-1
- 当前位置大于后一个位置则交换数据
- 代码实现
public static void main(String[] args) {
int[] arr = { 5, 2, 3, 1 };
// 总共循环【数组长度-1】次
for (int i = 0; i < arr.length; i++) {
// 每次循环比较【数组长度-循环轮次-1】次
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// 交换
arr[j] += arr[j + 1];
arr[j + 1] = arr[j] - arr[j + 1];
arr[j] = arr[j] - arr[j + 1];
}
}
}
System.out.println(Arrays.toString(arr));
}
1.3 选择排序
- 什么是选择排序:
- 每轮选择当前位置,开始找出后面的较小值与该位置交换
- 实现思路
- 先选择出数组的第一个元素,再选择出第二个元素,依次选择
- 实现选择排序的步骤:
- 确定总共需要循环几次:数组长度-1
- 控制每轮从以前位置为基准,与后面元素选择几次
- 代码实现
public static void main(String[] args) {
int[] arr = { 5, 2, 3, 1 };
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
arr[i] += arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
}
}
}
System.out.println(Arrays.toString(arr));
}
1.4 二分查找
- 什么是二分查找:
- 即折半查找,每次排除一半的数据
- 前提条件:数组中的数据必须是有序的
- 实现思路
- 定义一个头指针标记数组左部,定义一个尾指针标记数组右边,每次查找时比较头尾指针之间的中间指针
- 代码实现
public static void main(String[] args) {
int[] arr = { 7, 23, 79, 81, 103, 127, 131, 147 };
int mark = 79; // 查找的数据
int left = 0; // 左指针
int right = arr.length - 1; // 右指针
int mid = 0; // 中间指针
while (left <= right) { // 只有当左指针位于右指针的右边才中止循环
mid = (left + right) >> 1; // 中间指针位于左指针和右指针的中间
if (arr[mid] > mark) {
// 当前要找的元素如果小于中间元素,右边位置=中间索引-1
right = mid - 1;
} else if (arr[mid] < mark) {
// 当前要找的元素如果大于中间元素,左边位置=中间索引+1
left = mid + 1;
} else {
// 当前要找的元素如果等于中间元素,返回当前中间元素索引
System.out.println(mark + "在数组中的索引为" + mid);
return;
}
}
System.out.println("数组中不存在" + mark);
}
2. 正则表达式
2.1 概述
- 什么是正则表达式
- 由一些特定的字符组成,代表的是一个规则
- 有什么作用
- 可以用来校验数据格式是否合法
- 可以在一段文本中查找满足要求的内容
- String提供了一个匹配正则表达式的方法
public boolean matches(String regex);
- 判断字符串是否匹配正则表达式,匹配返回true,不匹配返回false
2.2 书写规则
符号 | 含义 | |
---|---|---|
? | 0次或1次 | |
* | 0次或多次 | |
+ | 1次或多次 | |
{} | 具体次数 | |
(?i) | 忽略后面字符的大小写 | |
a((?i)b)c | 只忽略b的大小写 | |
[] | 里面的内容出现一次 | |
^ | 取反 | |
&& | 交集,不能写单个的& | |
. | 任意字符 | |
\ | 转义字符 | |
\\d | 0-9 | |
\\D | 非0-9 | |
\\s | 空白字符 | |
\\S | 非空白字符 | |
\\w | 单词字符 | |
\\W | 非单词字符 | |
() | 分组 | |
` | ` | 写在方括号外面,表示并集 |
3. 异常
3.1 什么是异常
-
异常就是代表程序出现问题
-
异常的体系
- Error:代表的系统级别错误(属于严重问题),也就是说系统一旦出现问题,sun公司会把这些问题封装成Error对象给出来,说白了,Error是给sun公司自己用的,不是给我们程序员用的,因此我们开发人员不用管它
- Exception:叫异常,它代表的才是我们程序可能出现的问题,所以,我们程序员通常会用Exception以及它的子类来封装程序出现的问题
- 运行时异常:
RuntimeException
及其子类,编译阶段不会出现错误提醒,运行时出现的异常(如:数组索引越界异常) - 编译时异常:编译阶段就会出现错误提醒的。(如:日期解析异常)
- 运行时异常:
3.2 处理异常
- 抛出异常
// 在方法上使用throws关键字,可以将方法内部出现的异常抛出去给调用者处理
方法 throws 异常1, 异常2, ... {
...
}
- 捕获异常
// 将有可能出错的代码放入try代码块中,try能够直接捕获程序出现的异常
try {
// 监视可能出现异常的代码
} catch(异常1 变量) {
// 处理异常
} catch(异常n 变量) {
// 处理异常
} ...
3.3 自定义异常
Java无法为这个世界上全部的问题都提供异常类来代表, 如果企业自己的某种问题,想通过异常来表示,以便用异常来管理该问题,那就需要自己来定义异常类了。
- 自定义运行时异常
- 定义一个异常类继承
RuntimeException
- 重写构造器
- 通过throw new 异常类(xxx)来创建异常对象并抛出
- 定义一个异常类继承
- 自定义编译时异常
- 定义一个异常类继承
Exception
- 重写构造器
- 通过throw new 异常类(xxx)来创建异常对象并抛出
- 定义一个异常类继承