15_冒泡排序,选择排序,二分查找,正则表达式

Java SE 冒泡排序,选择排序,二分查找,正则表达式的使用

冒泡排序

思路:比较相邻的两个数, 如果第一个比第二个大, 交换

例:int[] arr = {2 , 5, 4, 3, 1}; 五个数据

第一轮 : arr[0]-arr[1] arr[1]-arr[2] arr[2]-arr[3] arr[3]-arr[4] 比较4次
第二轮 : arr[0]-arr[1] arr[1]-arr[2] arr[2]-arr[3] 比较3次
第三轮 : arr[0]-arr[1] arr[1]-arr[2] 比较2次
第四轮 : arr[0]-arr[1] 比较1次

实现
1
2
3
4
5
6
7
8
9
for (int i = 0; i < arr.length - 1; i++) {					// 内循环: 比较的次数
for (int j = 0; j < arr.length - 1 - i; j++) { // -1: 避免索引越界 -i: 提升代码效率
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}

选择排序

思路: 从 0 索引开始,拿着索引上的元素跟后一个的元素依次比较,如果小于后一个就交换,一轮结束后,最小的就到最左了。

例:int[] arr = {2 , 5, 4, 3, 1}; 五个数据

第一轮 : arr[0]-arr[1] arr[0]-arr[2] arr[0]-arr[3] arr[0]-arr[4]
第二轮 : arr[1]-arr[2] arr[1]-arr[3] arr[1]-arr[4]
第三轮 : arr[2]-arr[3] arr[2]-arr[4]
第四轮 : arr[3]-arr[4]

实现
1
2
3
4
5
6
7
8
9
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i+1; j < arr.length; j++) {
if(arr[i] > arr[j]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}

二分查找/折半查找

要求:数组是排好序的

思路
  • 元素如果大于中间元素 : min = mid + 1;
  • 元素如果小于中间元素 : max = mid – 1;
  • 元素如果等于中间元素 : 将索引返回 (mid)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static int binarySearch(int[] arr, int num) {
// 1. 定义两个变量记录最小索引, 最大索引
int min = 0;
int max = arr.length - 1;
int mid; // 判断后再赋值
// 2. 折半的动作不止一次, 使用循环
while (min <= max) {
// 3. 计算中间索引
mid = (min + max) / 2;
// 4. 判断
if (num > arr[mid]) {
min = mid + 1;
} else if (num < arr[mid]) {
max = mid - 1;
} else {
return mid;
}
}
// 5. 没找到, 返回-1
return -1;
}

正则表达式 [Pattern类]

专门表示正则的类:Pattern

用来校验字符串是否满足一定规则的字符串

使用方法

1
2
3
4
5
6
//规则
String regex = "编写规则";
"校验的字符串".matches(regex));
//示例
String regex = "\\d";
System.out.println("12".matches(regex)); //false

规则

  • 字符类
1
2
3
4
5
6
7
8
9
[] : 单个字符

[abc] 只能是a, b, 或c
[^abc] 除了a, b, c之外的任何字符
[a-zA-Z] az AZ,包括(范围)
[a-d[m-p]] ad,或m通过p:([a-dm-p]联合)
[a-z&&[def]] d, e, 或f(交集)
[a-z&&[^bc]] az,除了bc:([ad-z]减法)
[a-z&&[^m-p]] az,除了mp:([a-lq-z]减法)
  • 预定义字符类
1
2
3
4
5
6
7
8
.  		任何字符
\ 转义字符,对下一个字符分析
\d 一个数字: [0-9]
\D 非数字: [^0-9]
\s 一个空白字符: [ \t\n\x0B\f\r]
\S 非空白字符: [^\s]
\w [a-zA-Z_0-9] 英文、数字、下划线
\W [^\w] 一个非单词字符
  • 数量
1
2
3
4
5
6
X?	X, 		 一次或0
X* X, 零次或多次 (任意次数)
X+ X, 一次或多次
X {n} X, 正好n次
X {n, } X, 至少n次
X {n,m} X, 至少n但不超过m次

具体实例

  1. QQ号正则
    5~12位的数字,开头不为0
    String regex ="[1-9]\\d{4,11}";

  2. 手机号正则
    11位数字;1开头,第2个数字: 3 4 5 6 7 8 9
    String regex ="[1][3-9]\\d{9}";

  3. 邮箱正则

    ​ (数字字母下划线)@ (数字字母) . (2-3个字母) ;最后的可以多个

    如:abc123@163.com ; a_b_c_d@happy.qq.com

    String regex = "\\w+[@][\\w&&[^_]]+(\\.[a-z]{2,3})+";

    (\\.[a-z]{2,3})+:中间的规则可以出现一次或多次

String 类中与正则有关的常见方法

方法名 说明
public String replaceAll(String regex,String newStr) 按照正则表达式匹配的内容进行替换
public String[] split(String regex) 按照正则表达式匹配的内容进行分割字符串,反回一个字符串数组
1
2
String s = "abc1efg";
s = s.replaceAll("\\d", ""); //s = "abcefg"

正则表达式爬取信息

数据
1
2
3
4
5
String data = 
"电话:18666668888,18699997777或者联系" +
"邮箱:boniu@itcast.cn 邮箱:bozai@itcast.cn 邮箱2:dlei0009@163.com" +
"座机电话:01036517895,010-98951256 " +
"热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090";
获取
1
2
3
4
5
6
7
8
9
10
11
12
// 定义爬取的正则表达式
String regex = "[1][3-9]\\d{9}|\\w+[@][\\w&&[^_]]+(\\.[a-z]{2,3})+|[0]\\d{2,3}-?\\d{7,8}|400-?\\d{3}-?\\d{4}";

// 将正则表达式封装为 Pattern 对象
Pattern pattern = Pattern.compile(regex);

// 获取匹配器对象
Matcher matcher = pattern.matcher(data);

while (matcher.find()) { //匹配器查询有没有符合的数据,有就返还true,没有就有false;
System.out.println(matcher.group()); //打印符合的数据
}

注:

matcher.find():匹配器查询有没有符合规则的数据,有就返还true,没有为false; 然后指向后面数据,第二次调用就是看后面存不存在,然后matcher.group()获取该数据;

如果只使用一次matcher.find(),则matcher.group()内的数据始终相同。

输出
1
2
3
4
5
6
7
8
9
10
11
18666668888
18699997777
boniu@itcast.cn
bozai@itcast.cn
dlei0009@163.com
01036517895
010-98951256
400-618-9090
400-618-4000
4006184000
4006189090

15_冒泡排序,选择排序,二分查找,正则表达式
http://example.com/2023/02/15/15-冒泡排序,选择排序,二分查找,正则表达式/
作者
zhanghao
发布于
2023年2月15日
许可协议