当前位置: 首页 > news >正文

四、查找算法

文章目录

  • 一、查找算法介绍
  • 二、线性查找算法
    • 2.1 顺序查找
    • 2.2 二分查找(折半查找)
    • 2.3 插值查找
    • 2.4 斐波拉契(黄金分割法)查找算法
  • 三、树表的查找
    • 3.1 二叉排序树
      • 3.1.1 引入
      • 3.1.2 基本介绍
      • 3.1.3 二叉树的遍历
      • 3.1.4 二叉树的删除
    • 3.2 平衡二叉树
      • 3.2.1 基本介绍
      • 3.2.2 左旋转(对应RR型)
      • 3.2.3 右旋转(对应LL型)
      • 3.2.4 双旋转(对应LR型和RL型)
    • 3.3 B树
      • 3.3.1 引入
      • 3.3.2 B树的基本介绍
      • 3.3.3 2-3树
      • 3.3.4 B树、B+树和B*树
  • 四、散列(哈希)表
    • 4.1 散列(哈希)表引出
    • 4.2 散列(哈希)表的基本介绍
    • 4.3 散列(哈希)表 --- 应用实例

一、查找算法介绍

在这里插入图片描述

二、线性查找算法

2.1 顺序查找

在这里插入图片描述

package com.gyh.search;/*** @author Gao YongHao* @version 1.0*/
public class SeqSearch implements Search<Integer> {public static void main(String[] args) {Integer arr[] = {1, 9, 11, -1, 34, 89};int index = new SeqSearch().search(arr, -1);System.out.println(index);}@Overridepublic int search(Integer[] nums, Integer value) {for (int i = 0; i < nums.length; i++) {if (nums[i].equals(value)) {return i;}}return -1;}
}

2.2 二分查找(折半查找)

在这里插入图片描述

在这里插入图片描述

package com.gyh.search;import java.util.ArrayList;/*** @author Gao YongHao* @version 1.0* <p>* 注意:使用二分查找的前提是 该数组是有序的*/
public class BinarySearch implements Search<Integer> {public static void main(String[] args) {Integer[] arr = {-1, 11, 11, 11, 34, 89};BinarySearch binarySearch = new BinarySearch();int index = binarySearch.search(arr, 11);System.out.println(index);ArrayList<Integer> integers = binarySearch.searchAll(arr, 11);integers.forEach(System.out::println);}@Overridepublic int search(Integer[] nums, Integer value) {if (nums[0] > value || nums[nums.length - 1] < value) {return -1;}return search(nums, value, 0, nums.length - 1);}private int search(Integer[] nums, int value, int left, int right) {if (left > right) {return -1;}int mid = (left + right) / 2;if (nums[mid] < value) {return search(nums, value, mid + 1, right);} else if (nums[mid] > value) {return search(nums, value, left, mid - 1);} else {return mid; // 只返回一个值的写法}}@Overridepublic ArrayList<Integer> searchAll(Integer[] nums, Integer value) {if (nums[0] > value || nums[nums.length - 1] < value) {return new ArrayList<>();}return search2(nums, value, 0, nums.length - 1);}private ArrayList<Integer> search2(Integer[] nums, int value, int left, int right) {if (left > right) {return new ArrayList<>();}int mid = (left + right) / 2;if (nums[mid] < value) {return search2(nums, value, mid + 1, right);} else if (nums[mid] > value) {return search2(nums, value, left, mid - 1);} else {/*** 思路分析* 1. 在找到 mid 索引值,不要马上返回* 2. 向 mid 索引值的左边扫描,将所有满足 等于value的元素下标加入到集合 ArrayList中* 3. 向 mid 索引值的右边扫描,将所有满足 等于value的元素下标加入到集合 ArrayList中*/ArrayList<Integer> integers = new ArrayList<>();int temp = mid - 1;while (temp >= 0 && nums[temp].equals(nums[mid])) {integers.add(temp--);}integers.add(mid);temp = mid + 1;while (temp <= nums.length - 1 && nums[temp].equals(nums[mid])) {integers.add(temp++);}return integers;}}
}

2.3 插值查找

在这里插入图片描述

在这里插入图片描述

package com.gyh.search;import java.util.ArrayList;/*** @author Gao YongHao* @version 1.0*/
public class InsertSearch implements Search<Integer> {public static void main(String[] args) {Integer[] arr = {-1, 11, 11, 11, 34, 89};InsertSearch insertSearch = new InsertSearch();int index = insertSearch.search(arr, 11);System.out.println(index);}@Overridepublic int search(Integer[] nums, Integer value) {return search(nums, value, 0, nums.length - 1);}private int search(Integer[] nums, int value, int left, int right) {// 注意:value < nums[0]  和  value  > nums[nums.length -1 ] 的条件必须有// 否则得到的mid值可能越界(如value比nums的最大的数大得多 ...)if (left > right || value < nums[left] || value > nums[right]) {return -1;}// 自适应的midint mid = left + (value - nums[left]) / (nums[right] - nums[left]) * (right - left);if (nums[mid] < value) {return search(nums, value, mid + 1, right);} else if (nums[mid] > value) {return search(nums, value, left, mid - 1);} else {return mid; // 只返回一个值的写法}}}

2.4 斐波拉契(黄金分割法)查找算法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

package com.gyh.search;
import java.util.Arrays;/*** @author Gao YongHao* @version 1.0*/
public class FibonacciSearch implements Search<Integer> {private static final int MAX = 20;public static void main(String[] args) {Integer[] arr = {-1, 11, 11, 11, 34, 89};FibonacciSearch fibonacciSearch = new FibonacciSearch();int index = fibonacciSearch.search(arr, -1);System.out.println(index);}@Overridepublic int search(Integer[] nums, Integer value) {int low = 0;int high = nums.length - 1;int k = 0; // 表示斐波拉契分割数值的下标int mid = 0; // 表示存放mid值int[] f = fib(); // 获取到斐波拉契数列// 获取到斐波那契分割数值的下标while (high > f[k] - 1) {k++;}// 因为 f[k] 值可能大于 nums 的长度,因此我们需要使用Arrays类,构造一个新的数组,并指向a[]// 不足的部分会使用 0 填充Integer[] temp = Arrays.copyOf(nums, f[k]);// 实际上需求使用 nums 数组最后的数填充 temp// 只需要对总数据作一次填充即可for (int i = high + 1; i < temp.length; i++) {temp[i] = nums[high];}// 与二分查找类似使用while数组处理,找到我们的数 keywhile (low <= high) {mid = low + f[k - 1] - 1; // 黄金分割点位置if (value < temp[mid]) { // 我们应该继续向左继续向数组的前面查找high = mid - 1;/*** 为什么 k--* 说明* 1. 全部元素 = 前面的元素 + 后面的元素* 2. f[k] = f[k-1] + f[k-2]* 因为 前面的有 f[k-1] 元素,所以可以继续拆分 f[k-1] = f[k-2] + f[k-3]* 即 在前面的f[k-1]继续查找 k--* 即 下次循环 mid = low + f[k-1-1]-1*/k--;} else if (value > temp[mid]) {low = mid + 1;/*** 为什么是 k-=2* 说明* 1. 全部元素 = 前面的元素 + 后面的元素* 2. f[k] = f[k-1] + f[k-2]* 3. 因为后面我们有f[k-2]个数所以可以继续拆分 f[k-2] = f[k-3] + f[k-4]* 4. 即在后面的f[k-2]继续查找 k-=2* 5. 即下次循环 mid = low + f[k-1-2]-1*/k -= 2;} else { // 找到// 需要确定,返回的是哪个下标// 存在最终定位的 mid 是由原数组最大值扩充的元素return Math.min(mid, high);}}return -1;}private int[] fib() {int[] fs = new int[MAX];for (int i = 0; i < MAX; i++) {if (i == 0 || i == 1) {fs[i] = 1;continue;}fs[i] = fs[i - 1] + fs[i - 2];}return fs;}}

三、树表的查找

3.1 二叉排序树

3.1.1 引入

在这里插入图片描述

在这里插入图片描述

3.1.2 基本介绍

在这里插入图片描述

3.1.3 二叉树的遍历

在这里插入图片描述

package com.gyh.tree;/*** @author Gao YongHao* @version 1.0*/
public class BinarySortTree {public static void main(String[] args) {int[] arr = {7, 3, 10, 12, 5, 1, 9};BNode binarySortTree = new BinarySortTree().createBinarySortTree(arr);new BinarySortTree().midOrder(binarySortTree);}public void midOrder(BNode node) {if (node == null) {return;}midOrder(node.left);System.out.println(node.n);midOrder(node.right);}public BNode createBinarySortTree(int[] arr) {if (arr == null || arr.length <= 0) {return null;}BNode root = new BNode(arr[0]);BNode tNode;for (int i = 1; i < arr.length; i++) {tNode = root;while (true) {if (arr[i] < tNode.n) {if (tNode.left == null) {tNode.left = new BNode(arr[i]);break;} else {tNode = tNode.left;}} else {if (tNode.right == null) {tNode.right = new BNode(arr[i]);break;} else {tNode = tNode.right;}}}}return root;}
}class BNode {int n;BNode left;BNode right;public BNode(int n) {this.n = n;}public BNode(int n, BNode left, BNode right) {this.n = n;this.left = left;this.right = right;}
}

3.1.4 二叉树的删除

  • 主要思想:
  1. 前提是 需要有指向 当前结点其双亲结点 的变量
  2. 若当前结点是叶子结点,直接删除
  3. 若当前结点的孩子结点只有一个(左或右),将当前结点的左(右)孩子赋给双亲结点的指向当前结点的变量(parent.leftparent.right)
  4. 若当前结点的孩子结点有两个,则使用当前结点的右子树的中最小值对应的结点填充到这个位置(再该填充值原来的位置的结点); 或使用当前结点的左子树的中最大值对应的结点填充到这个位置(再该填充值原来的位置的结点)
    在这里插入图片描述
package com.gyh.tree;/*** @author Gao YongHao* @version 1.0*/
public class BinarySortTree {private BNode root;public static void main(String[] args) {int[] arr = {7, 3, 10, 12, 5, 1, 9};BNode binarySortTree = BinarySortTree.createBinarySortTree(arr);new BinarySortTree(binarySortTree).midOrder();new BinarySortTree(binarySortTree).remove(7);new BinarySortTree(binarySortTree).midOrder();}public BinarySortTree(BNode root) {this.root = root;}public void midOrder() {midOrder(root);}private void midOrder(BNode bn) {if (bn == null) {return;}midOrder(bn.left);System.out.println(bn.n);midOrder(bn.right);}// 查找要删除的结点private BNode search(BNode bn, int value) {if (bn == null) {return null;}if (value < bn.n) {return search(bn.left, value);} else if (value > bn.n) {return search(bn.right, value);} else {return bn;}}// 查找要删除结点的父节点private BNode searchParent(BNode bn, int value) {if ((bn.left != null && bn.left.n == value) || (bn.right != null && bn.right.n == value)) {return bn;} else {if (value < bn.n && bn.left != null) {return searchParent(bn.left, value); // 向左子树寻找} else if (value > bn.n && bn.right != null) {return searchParent(bn.right, value); // 向右子树寻找} else {return null;}}}public void remove(int value) {remove(root, value);}public void remove(BNode bn, int value) {// 1、寻找要删除的结点BNode node;if (root == null || (node = search(bn, value)) == null) {return;}// 2、寻找要删除的结点的父结点BNode pNode = searchParent(root, value);// 若是叶子结点则直接删除后,重置其父节点的指向if (node.left == null && node.right == null) {if (pNode == null) {// 删除根节点信息并退出root = null;return;}if (pNode.left == node) {pNode.left = null;} else {pNode.right = null;}} else if (node.left == null) { // 若只有一棵子树if (pNode == null) {// 删除根节点root = node.right;return;}if (pNode.left == node) {pNode.left = node.right;} else {pNode.right = node.right;}} else if (node.right == null) {if (pNode == null) {// 删除根节点root = node.left;return;}if (pNode.left == node) {pNode.left = node.left;} else {pNode.right = node.left;}} else { // 有两棵子树// 方式一:找左子树的最大值(最右的结点)
//            BNode lNode = node.left;
//            while (lNode.right != null) {
//                lNode = lNode.right;
//            }
//            // 删除左边的最大值点
//            remove(node, lNode.n);
//            // 将左边的最大值赋给当前结点
//            node.n = lNode.n;// 方式二:找右子树的最小值(最最的结点)BNode rNode = node.right;while (rNode.left != null) {rNode = rNode.left;}// 删除右边的最小值点remove(node, rNode.n);// 将右边的最小值赋给当前结点node.n = rNode.n;}}public static BNode createBinarySortTree(int[] arr) {if (arr == null || arr.length <= 0) {return null;}BNode root = new BNode(arr[0]);BNode tNode;for (int i = 1; i < arr.length; i++) {tNode = root;while (true) {if (arr[i] < tNode.n) {if (tNode.left == null) {tNode.left = new BNode(arr[i]);break;} else {tNode = tNode.left;}} else {if (tNode.right == null) {tNode.right = new BNode(arr[i]);break;} else {tNode = tNode.right;}}}}return root;}
}class BNode {int n;BNode left;BNode right;public BNode(int n) {this.n = n;}public BNode(int n, BNode left, BNode right) {this.n = n;this.left = left;this.right = right;}
}

3.2 平衡二叉树

在这里插入图片描述

3.2.1 基本介绍

  • 平衡二叉树的平衡调整方法
    在插入结点时,首先按照二叉排序树处理,若插入结点后破坏了平衡二叉树的特性,需要对平衡二叉树进行调整。调整方法是:找到离插入结点最近且平衡因子绝对值超过1的祖先结点,以该结点为根的子树称为 最小不平衡子树,可将重新平衡的范围局限于这棵树。
    在这里插入图片描述

3.2.2 左旋转(对应RR型)

在这里插入图片描述

在这里插入图片描述

3.2.3 右旋转(对应LL型)

在这里插入图片描述

3.2.4 双旋转(对应LR型和RL型)

在这里插入图片描述

在这里插入图片描述

package com.gyh.tree;/*** @author Gao YongHao* @version 1.0* <p>* 平衡二叉树*/
public class BalancedBinaryTree {public static void main(String[] args) {int[] arr = {4, 3, 6, 5, 7, 8};BBNode binarySortTree = BalancedBinaryTree.createBinarySortTree(arr);BalancedBinaryTree.midOrder(binarySortTree);System.out.println("树的高度:" + BalancedBinaryTree.height(binarySortTree));System.out.println("树的左子树高度:" + BalancedBinaryTree.leftHeight(binarySortTree));System.out.println("树的右子树高度:" + BalancedBinaryTree.rightHeight(binarySortTree));}// RR 型对应左旋转public static void leftRote(BBNode root) {// 创建一个新节点,以当前根节点的值BBNode bbNode = new BBNode(root.d);// 把新的结点的左子树根节点值设置成当前结点的左子树根节点值bbNode.left = root.left;// 把新的结点的右子树节点值设置成当前结点的右子树的左子树节点值bbNode.right = root.right.left;// 把当前结点的值替换为右子树节点值root.d = root.right.d;// 把当前结点的右子树设置为右子树的右子树节点值root.right = root.right.right;// 把当前结点的左子树设置为新节点root.left = bbNode;}// LL型对应右旋转private static void rightRote(BBNode root) {BBNode bbNode = new BBNode(root.d);bbNode.right = root.right;bbNode.left = root.left.right;root.d = root.left.d;root.left = root.left.left;root.right = bbNode;}public static void midOrder(BBNode bn) {if (bn == null) {return;}midOrder(bn.left);System.out.println(bn.d);midOrder(bn.right);}// 计算平衡因子private static int avlFactor(BBNode bbn) {return leftHeight(bbn) - rightHeight(bbn);}// 平衡化过程// 本例中并没有寻找最小不平衡子树,直接对根进行平衡化操作(此操作过程有误,仅实验方法)private static void avl(BBNode root) {if (root == null) {return;}// 计算左子树高 和 右子树高int avlFactor = avlFactor(root);int leftAvlFactor;if (root.left == null) {leftAvlFactor = 0;} else {leftAvlFactor = avlFactor(root.left);}int rightAvlFactor;if (root.right == null) {rightAvlFactor = 0;} else {rightAvlFactor = avlFactor(root.right);}if (avlFactor == -2 && rightAvlFactor == -1) { // 需要左旋转leftRote(root);}if (avlFactor == -2 && rightAvlFactor == 1) { // 先右后左旋转rightRote(root.right);leftRote(root);return;}if (avlFactor == 2 && leftAvlFactor == 1) { // 需要右旋转rightRote(root);return;}if (avlFactor == 2 && leftAvlFactor == -1) { // 需要左后右旋转leftRote(root.left);rightRote(root);}}public static BBNode createBinarySortTree(int[] arr) {if (arr == null || arr.length <= 0) {return null;}BBNode root = new BBNode(arr[0]);BBNode tNode;for (int i = 1; i < arr.length; i++) {tNode = root;while (true) {if (arr[i] < tNode.d) {if (tNode.left == null) {// 添加新值tNode.left = new BBNode(arr[i]);// 平衡化处理avl(root);break;} else {tNode = tNode.left;}} else {if (tNode.right == null) {tNode.right = new BBNode(arr[i]);// 平衡化处理avl(root);break;} else {tNode = tNode.right;}}}}return root;}public static int leftHeight(BBNode bbn) {return height(bbn.left);}public static int rightHeight(BBNode bbn) {return height(bbn.right);}public static int height(BBNode bbn) {if (bbn == null) {return 0;}return Math.max(height(bbn.left), height(bbn.right)) + 1;}
}class BBNode {int d;BBNode left;BBNode right;public BBNode(int d) {this.d = d;}
}

3.3 B树

3.3.1 引入

在这里插入图片描述

在这里插入图片描述

3.3.2 B树的基本介绍

  • 定义见书上 P210
    在这里插入图片描述

3.3.3 2-3树

  • 3阶(阶数代表最大分叉数)的B树,至多可有两个关键字,至少有一个关键字(即子树个数为2或者3,故成为 2-3树
    在这里插入图片描述

在这里插入图片描述

  • 插入时的分裂方法参见书 P214

在这里插入图片描述

3.3.4 B树、B+树和B*树

在这里插入图片描述

  • B树
    在这里插入图片描述

  • 注意:对B树数据存放位置的描述(可能存在于叶子结点非叶子结点

  • B+树
    在这里插入图片描述

  • 注意:对B+树数据存放位置的描述(只存在于叶子结点

  • B*树
    在这里插入图片描述

四、散列(哈希)表

4.1 散列(哈希)表引出

在这里插入图片描述

4.2 散列(哈希)表的基本介绍

在这里插入图片描述

4.3 散列(哈希)表 — 应用实例

在这里插入图片描述

package com.gyh.search;import java.util.HashMap;
import java.util.Objects;/*** @author Gao YongHao* @version 1.0*/
@SuppressWarnings("all")
public class HashTableDemo<K, V> {public static void main(String[] args) {HashTableDemo<Integer, Emp> hashTab = new HashTableDemo<Integer, Emp>();hashTab.put(1, new Emp(1, "aa", 1, 12, "zg"));hashTab.put(1, new Emp(1, "bb", 1, 12, "33"));hashTab.put(1, new Emp(1, "dd", 1, 12, "dd"));hashTab.put(101, new Emp(101, "cc", 1, 12, "55"));System.out.println(hashTab.get(1));}// 数组private Node<K, V>[] table;// 设置最大的容量private static int MAX = 100;private int size = 0;// 不考虑扩容public HashTableDemo() {table = (Node<K, V>[]) new Node[MAX];}public void put(K k, V v) {putVal(hash(k), k, v);}public V get(K k) {
//        HashMapint hash;Node<K, V> n, e;if (size > 0 && (e = table[hash = hash(k)]) != null) {// 遍历位于同一位置的单链表上的元素while (e != null) {if (hash == e.hash && (k == e.k || k.equals(e.k))) {return e.v;}e = e.next;}}return null;}private void putVal(int hash, K k, V v) {Node<K, V> cur, p;// 该位置没有初始的数值if ((cur = table[hash]) == null) {table[hash] = new Node<>(hash, k, v, null);size++;} else { // 遍历链表中的元素。相等则值替换,不等则直接添加至最后while (cur != null) {if (hash == cur.hash && (k == cur.k || k.equals(cur.k))) {// 表示相同则值替换cur.v = v;break;}// 若是最后一个元素则添加if ((p = cur.next) == null) {cur.next = new Node<>(hash, k, v, null);size++;break;} else {cur = p;}}}}// 散列函数计算存储的位置(除留余数法)private int hash(K v) {int h = v.hashCode();return h % MAX;}}class Node<K, V> {int hash;K k;V v;Node<K, V> next;public Node(int hash, K k, V v, Node<K, V> next) {this.hash = hash;this.k = k;this.v = v;this.next = next;}
}class Emp {private int id; // 雇员的Idprivate String name; // 名字private int gender; // 性别private int age; // 年龄private String address; // 地址public Emp() {}@Overridepublic String toString() {return "Emp{" +"id=" + id +", name='" + name + '\'' +", gender=" + gender +", age=" + age +", address='" + address + '\'' +'}';}public Emp(int id, String name, int gender, int age, String address) {this.id = id;this.name = name;this.gender = gender;this.age = age;this.address = address;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getGender() {return gender;}public void setGender(int gender) {this.gender = gender;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Emp emp = (Emp) o;return id == emp.id &&gender == emp.gender &&age == emp.age &&Objects.equals(name, emp.name) &&Objects.equals(address, emp.address);}@Overridepublic int hashCode() {return id; // 当前任务使用 id 作为 hashCode}
}

相关文章:

四、查找算法

文章目录 一、查找算法介绍二、线性查找算法2.1 顺序查找2.2 二分查找&#xff08;折半查找&#xff09;2.3 插值查找2.4 斐波拉契&#xff08;黄金分割法&#xff09;查找算法 三、树表的查找3.1 二叉排序树3.1.1 引入3.1.2 基本介绍3.1.3 二叉树的遍历3.1.4 二叉树的删除 3.2…...

果蔬识别系统性能优化之路(三)

目录 前情提要遗留问题 解决方案优化查询速度优化ivf初始化的速度 下一步 前情提要 果蔬识别系统性能优化之路&#xff08;二&#xff09; 遗留问题 优化同步速度&#xff0c;目前大约30秒&#xff0c;不是一个生产速度 这次来解决遗留问题 通过console&#xff0c;发现两个…...

时序预测|基于小龙虾优化高斯过程GPR数据回归预测Matlab程序COA-GPR 多特征输入单输出 附赠基础GPR

时序预测|基于小龙虾优化高斯过程GPR数据回归预测Matlab程序COA-GPR 多特征输入单输出 附赠基础GPR 文章目录 一、基本原理二、实验结果三、核心代码四、代码获取五、总结 时序预测|基于小龙虾优化高斯过程GPR数据回归预测Matlab程序COA-GPR 多特征输入单输出 附赠基础GPR 一、…...

C#进阶-快速了解IOC控制反转及相关框架的使用

目录 一、了解IOC 1、概念 2、生命周期 二、IOC服务示例 1、定义服务接口 2、实现服务 三、扩展-CommunityToolkit.Mvvm工具包 Messenger信使 方式一&#xff08;收发消息&#xff09; 方式二&#xff08;收发消息&#xff09; 方式三&#xff08;请求消息&#xf…...

C++内存布局

文章目录 C内存布局1.文字介绍2.图片介绍3.代码介绍 C内存布局 1.文字介绍 1.内核态空间 2.用户态空间 (1)栈区&#xff1a;存储局部变量和函数调用的相关信息&#xff0c;栈的特点是自动分配和释放&#xff0c;由操作系统管理。栈由高地址向低地址生长&#xff0c;通常为0x…...

【Linux 19】线程概念

文章目录 &#x1f308; 一、线程的概念⭐ 1. 线程是什么⭐ 2. 线程的优点⭐ 3. 线程的缺点⭐ 4. 线程的异常⭐ 5. 线程的用途 &#x1f308; 二、进程和线程⭐ 1. 进程和线程的区别⭐ 2. 进程的多线程共享⭐ 3. 进程和线程的关系⭐ 3. 进程和线程的关系 &#x1f308; 一、线程…...

[区间dp]添加括号

题目描述 有一个 n n n 个元素的数组 a a a。不改变序列中每个元素在序列中的位置&#xff0c;把它们相加&#xff0c;并用括号记每次加法所得的和&#xff0c;称为中间和。现在要添上 n − 1 n - 1 n−1 对括号&#xff0c;加法运算依括号顺序进行&#xff0c;得到 n − …...

jenkins流水线+k8s部署springcloud微服务架构项目

文章目录 1.k8s安装2.jenkins安装3.k8s重要知识1.简介2.核心概念3.重要命令1.查看集群消息2.命名空间3.资源创建/更新4.资源查看5.描述某个资源的详细信息6.资源编辑7.资源删除8.资源重启9.查看资源日志10.资源标签 4.k8s控制台1.登录2.界面基本操作1.选择命名空间2.查看命名空…...

安卓开发板_联发科MTK开发评估套件串口调试

串口调试 如果正在进行lk(little kernel ) 或内核开发&#xff0c;USB 串口适配器&#xff08; USB 转串口 TTL 适配器的简称&#xff09;对于检查系统启动日志非常有用&#xff0c;特别是在没有图形桌面显示的情况下。 1.选购适配器 常用的许多 USB 转串口的适配器&#xf…...

vue+el-table 可输入表格使用上下键进行input框切换

使用上下键进行完工数量这一列的切换 <el-table :data"form.detailList" selection-change"handleChildSelection" ref"bChangeOrderChild" max-height"500"><!-- <el-table-column type"selection" width&quo…...

中国书法——孙溟㠭浅析碑帖《三希堂法帖》

孙溟㠭浅析碑帖《三希堂法帖》 全称是《三希堂石渠宝笈法帖》&#xff0c;是中国清代宫廷刻帖&#xff0c;一共三十二册。 清朝高宗弘历收藏了晋王羲之《快雪时晴帖》&#xff0c;王献之的《中秋帖》&#xff0c;王珣的《伯远帖》三种王氏原墨迹。故而把所藏法书之所…...

深入探讨生成对抗网络(GANs):颠覆传统的AI创作方式

在人工智能的快速发展中&#xff0c;生成对抗网络&#xff08;Generative Adversarial Networks, GANs&#xff09;无疑是一个引人注目的技术。自2014年由Ian Goodfellow等人首次提出以来&#xff0c;GANs已经在图像生成、文本生成、视频生成等多个领域展现出了惊人的能力。本文…...

vmware Vnet8虚拟网卡丢失的找回问题

vmware Vnet8虚拟网卡丢失的找回问题 1.打开VMware Workstation 2.然后点击Edit --> Virtual Network Edit --> 打开Virtual Network Edit框 &#xff0c; 3.点击最下面的的Restore Default 按钮&#xff0c; 3.恢复默认设置&#xff0c;这会在网络连接那块可以看到丢失…...

Python 从入门到实战13(字符串简介)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们通过举例学习了流程控制语句中的循环语句。今天继续讨…...

Redis_RDB持久化

基于RDB的持久化方式会把当前内存中所有的redis键值对数据以快照的方式写入硬盘文件中&#xff0c;如果需要恢复数据&#xff0c;就把快照文件读到内存中。 RDB快照文件是经压缩的二进制格式的文件&#xff0c;它的储存路径不仅可以在redis服务器启动前通过配置参数来设置&…...

SOP流程制定:vioovi ECRS工时分析软件的智慧引领

在现代制造业中&#xff0c;标准化操作流程&#xff08;SOP&#xff09;已成为提升生产效率、确保产品质量、降低运营成本的关键要素。SOP不仅为生产活动提供了明确的指导&#xff0c;还促进了企业管理的规范化和精细化。然而&#xff0c;如何科学、高效地制定SOP流程&#xff…...

并发编程-synchronized解决原子性问题

并发编程-synchronized解决原子性问题 文章目录 并发编程-synchronized解决原子性问题零、说在前面一、线程安全问题1.1 什么是线程安全问题1.2 自增运算不是线程安全的1.3 临界区资源与临界区代码段 二、synchronized 关键字的使用2.1 synchronized 关键字作用2.2 synchronize…...

CSS之我不会

非常推荐html-css学习视频&#xff1a;尚硅谷html-css 一、选择器 作用&#xff1a;选择页面上的某一个后者某一类元素 基本选择器 1.标签选择器 格式&#xff1a;标签{} <h1>666</h1><style>h1{css语法} </style>2.类选择器 格式&#xff1a;.类…...

AI绘画:SD打光神器!(Stable Diffusion进阶篇:Imposing Consistent Light)

前言 在上一篇笔记中学习了如何简单地下载以及使用IC-Light&#xff0c;今天的内容会稍微有点不一样。 对于学过stable diffusion的小伙伴来说&#xff0c;forge UI和Comfy UI会更加熟悉一些。在IC-Light发布后&#xff0c;Openpose editor的开发者将其制作成了一个Forge UI上…...

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第二期]

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第二期] 第二期介绍&#xff1a;频道模块之频道管理 目录 QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第二期]第二期介绍&#xff1a;频道模块之频道管理获取用户详情获取用户频道列表获取频道详情获取子频道列表获…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版

1.题目描述 2.思路 当前的元素可以重复使用。 &#xff08;1&#xff09;确定回溯算法函数的参数和返回值&#xff08;一般是void类型&#xff09; &#xff08;2&#xff09;因为是用递归实现的&#xff0c;所以我们要确定终止条件 &#xff08;3&#xff09;单层搜索逻辑 二…...

CTF show 数学不及格

拿到题目先查一下壳&#xff0c;看一下信息 发现是一个ELF文件&#xff0c;64位的 ​ 用IDA Pro 64 打开这个文件 ​ 然后点击F5进行伪代码转换 可以看到有五个if判断&#xff0c;第一个argc ! 5这个判断并没有起太大作用&#xff0c;主要是下面四个if判断 ​ 根据题目…...

深度解析:etcd 在 Milvus 向量数据库中的关键作用

目录 &#x1f680; 深度解析&#xff1a;etcd 在 Milvus 向量数据库中的关键作用 &#x1f4a1; 什么是 etcd&#xff1f; &#x1f9e0; Milvus 架构简介 &#x1f4e6; etcd 在 Milvus 中的核心作用 &#x1f527; 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...