# 常见算法

算法:解决某个实际问题的过程和方法

# 冒泡排序

每次从数组中找出最大值放在数组的后面去

实现关键步骤:

  • 确定总共需要做几轮: 数组的长度-1
  • 每轮比较几次
  • 当前位置大于后一个位置则交换数据
演示

1667403618904

public class Test {
  public static void main(String[] args) {
    int[] arr = {5, 2, 3, 1};
    for (int i = 0; i < arr.length - 1; i++) {
      for (int j = 0; j < arr.length - i - 1; j++) {
        if (arr[j] > arr[j + 1]) {
          int temp = arr[j + 1];
          arr[j + 1] = arr[j];
          arr[j] = temp;
        }
      }
    }
    System.out.println(Arrays.toString(arr));
  }
}

动画演示

# 选择排序

每轮选择当前位置,开始找出后面的较小值与该位置交换

实现关键步骤

  • 确定总共需要选择几轮: 数组的长度-1
  • 控制每轮从以前位置为基准,与后面元素选择几次
演示
public class Test {
  public static void main(String[] args) {
    int[] arr = {5, 2, 3, 1};
    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;
        }
      }
    }
    // 进一步优化
    for (int i = 0; i < arr.length - 1; i++) {
      int minIndex = i;
      for (int j = i + 1; j < arr.length; j++) {
        if (arr[minIndex] > arr[j]) {
          minIndex = j;
        }
      }
      if (i != minIndex) {
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
      }
    }
    System.out.println(Arrays.toString(arr));
  }
}

动画演示

# 查找算法 👇🏻

# 基本查找(顺序查找)

从前往后挨个查找

数据量大的时候,性能很差

# 二分查找(折半查找)

前提条件:数组中的数据必须是有序的

核心思想:每次排除一半的数据,查询数据的性能明显提高极多

二分查找正常的折半条件应该是 开始位置left <= 结束位置right

public class Test {
  public static void main(String[] args) {
    int[] arr = {7, 23, 79, 81, 103, 127, 131, 147};
    System.out.println(binarySearch(arr, 150));
    //java 自带的方法
    System.out.println(Arrays.binarySearch(arr, 81));
  }
  public static int binarySearch(int[] arr, int data) {
    int left = 0;
    int right = arr.length - 1;
    while (left <= right) {
      int middle = (left + right) / 2;
      if (data < arr[middle]) {
        // 往左边找,截止位置(右边位置) = 中间位置 - 1
        right = middle - 1;
      } else if(data > arr[middle]) {
        // 往右边找,起始位置(左边位置) = 中间位置 + 1
        left = middle + 1;
      } else {
        // 中间位置处的元素值,正好等于要找的元素值
        return middle;
      }
    }
    return -1; // 没有找到数据
  }
}

# 正则表达式

由一些特定的字符组成,代表的是一个规则

  • 用来校验数据格式是否合法
  • 在一段文本中查找满足要求的内容

String 提供了一个匹配正则表达式的方法:

方法名说明
public boolean matches(String regex)判断字符串是否匹配正则表达式
匹配返回 true,不匹配返回 false

# 书写规则

符号含义举例
数量词 👇🏻
?0 次或 1 次\\d? ➡ 0 次或 1 次的数字
*0 次或多次\\d* ➡ 0 次或 1 次的数字
(abc)* ➡ 0 次或 1 次的 abc
+1 次或多次\\d+ ➡ 1 次或多次的数字
(abc)+ ➡ 1 次或多次的 abc
{}具体次数X {n} ➡ X,正好 n 次
X {n,} ➡ X,至少 n 次
X {n,m} ➡ X,至少 n 但不超过 m 次
字符类(只匹配单个字符)👇🏻
(?i)忽略后面字符的大小写(?i) abc ➡ 忽略 abc 的大小写
a ((?i) b) c ➡ 只忽略 b 的大小写
[]里面的内容出现一次[abc] ➡ 只能是 a, b, 或 c
^取反[^abc] ➡ 除了 a, b, c 之外的任何字符
&&交集,不能写单个的 &[a-z&&m-p] ➡ m-p 的小写字母
预定义字符(只匹配单个字符)👇🏻
.任意字符\n 回车符号不匹配
\转义字符\d ➡ 0-9
\\d0-9\\d+ ➡ 1 次或多次的数字
\\D非 0-9\\D+ ➡ 1 次或多次的数字
\\s空白字符
\\S非空白字符[^\s] ➡ 一个非空白字符
\\w单词字符等同于 [a-zA-Z_0-9]
\\W非单词字符[^\w] ➡ 一个非单词字符
()分组a (bc)+ ➡ a 和 1 次或多次的 bc
|写在方括号外面表示并集ab|AB ➡ ab 或 AB

# 应用案例

校验用户输入的电话、邮箱、时间是否合法

# 信息爬取

# 搜索替换