常见算法和Lambda表达式

news2024/11/17 3:42:52

常见算法和Lambda

常见算法

查找算法

基本查找

从0索引开始逐个查找

代码演示:

package Search;

import java.util.ArrayList;

public class BasicSearch {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,3,4,1,3};
        ArrayList<Integer> resArr = basicFind(arr, 3);
        for (int i = 0; i < resArr.size(); i++) {
            System.out.print(resArr.get(i) + " ");
        }

    }

    public static ArrayList<Integer> basicFind(int[] arr, int num){
        ArrayList<Integer> res = new ArrayList<>();
        int index = 0;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == num) res.add(i);
        }
        return res;
    }
}
二分查找
概述

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

核心逻辑: 每次排除一半的查找范围

public static int binarySearch(int[] arr, int num){
        int n = arr.length;
        int l = 0, r = n - 1;
        while(l <= r){
            int mid = l + (r - l) / 2;
            if(arr[mid] == num) return mid;
            else if(arr[mid] > num){
                r = mid - 1;
            }
            else{
                l = mid + 1;
            }
        }
        return -1;
    }

总结

1.二分查找的优势?

  • 提前查找效率

2.二分查找的前提条件?

  • 数据必须是有序的
  • 如果数据是乱的,先排席再用二分查找得到的索引没有实际意义,只能确定当前数字在数组中是否存在,因为排序之后数字的位置就可能发生变化了

3.二分查找的过程

  • min和max表示当前要查找的范围
  • mid是在min和max中间的
  • 如果要查找的元素在mid的左边,缩小范围时min不变,max等于mid减1如果要查找的元素在mid的右边,缩小范围时, max不变,min等于mid加1
插值查找

计算mid的时候可以进行改进
m i d = m i n + k e y − a r r [ m i n ] a r r [ m a x ] − a r r [ m i n ] ∗ ( m a x − m i n ) mid = min + \frac{key - arr[min]}{arr[max] - arr[min]} * (max - min) mid=min+arr[max]arr[min]keyarr[min](maxmin)
也叫插值查找, 数组中的数据分布比较均匀的话会更快

分块查找

分块的原则1: 块内无序, 块之间有序

分块原则2 : 块数数量一般等于总数开根号

核心思路: 先确定要查找的元素在哪一块, 然后在块内逐个查找

实现步骤

  1. 创建数组blockArr存放每一个块对象的信息
  2. 先查找blockArr确定要查找的数据属于哪一块
  3. 在单独遍历这一块数据即可

代码:

package Search;

public class BlockSearch {
    public static void main(String[] args) {
        int[] arr = {16, 5, 9, 12, 21, 18,
                     32, 23, 37, 26, 45, 34,
                     50, 48, 61, 52, 73, 66};

        // 创建数组
        Block b1 = new Block(21, 0, 5);
        Block b2 = new Block(45, 6, 11);
        Block b3 = new Block(73, 12, 17);
        Block[] block = {b1, b2, b3};
        int index = blockSearch(arr, block, 37);
        System.out.println(index);


    }

    public static int blockSearch(int[] arr, Block[] block, int num){
        // 先判断num属于哪一块
        int blockIndex = getBlockIndex(block, num);
        int startIndex = block[blockIndex].getStartIndex();
        int endIndex = block[blockIndex].getEndIndex();
        for(int i = startIndex; i <= endIndex; ++i){
            if(arr[i] == num){
                return i;
            }
        }
        return -1;
    }
    
	// 找出num属于哪个分块
    private static int getBlockIndex(Block[] block, int num) {
        for (int i = 0; i < block.length; i++) {
            if(num <= block[i].getBlockMax()){
                return i;
            }
        }
        return -1;
    }
}

// 标准JavaBean
class Block{
    private int blockMax;
    private int startIndex;
    private int endIndex;

    public int getBlockMax() {
        return blockMax;
    }

    public Block() {
    }

    public Block(int blockMax, int startIndex, int endIndex) {
        this.blockMax = blockMax;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
    }

    public void setBlockMax(int blockMax) {
        this.blockMax = blockMax;
    }

    public int getStartIndex() {
        return startIndex;
    }

    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }

    public int getEndIndex() {
        return endIndex;
    }

    public void setEndIndex(int endIndex) {
        this.endIndex = endIndex;
    }
}

扩展的分块查找(无规律的数据)
在这里插入图片描述

在这里插入图片描述

排序算法

冒泡排序

相邻的数据两两比较, 小的放前面, 大的放后面

第一轮循环结束, 最大值已经找到, 在数组的最右边

第二轮循环只要在剩余的元素找最大值就可以了 …

代码演示:

package SortDemo;

public class BubbleSort {
    public static void main(String[] args) {
        int[] arr = {2,4,5,6,3,1,7,12,9,8,10,11,0};
        myBubbleSort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

    // 外循环表示轮数, 有n个数据, 就要执行n-1轮
    private static void myBubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n; ++i) {
            boolean swapped = false;
            // 内循环, 每一轮中找到最大值
            // -1是为了防止数组越界
            // -i为了提高效率, 每一轮执行的次数比上一轮少执行一次
            for (int j = 0; j < n - i - 1; ++j){
                if(arr[j] > arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                    swapped = true;
                }
            }
            // 如果遍历一轮都没发生交换,说明数组已经有序,直接返回即可
            if(!swapped) return;
        }
    }
}
选择排序

从索引0开始, 拿着每一个索引上的元素跟后面的元素依次比较, 小的放前面, 大的放后面, 以此类推

第一轮循环结束后, 最小的数据已经确定 …

private static void mySelectSort(int[] arr) {
    int n = arr.length;
    for(int i = 0; i < n; ++i){
        int min = i;
        for(int j = i + 1; j < n; ++j){
            if(arr[j] < arr[min]) min = j;
        }
        if(min != i) swap(arr, min, i);
    }
}
插入排序

插入排序:

将0索引的元素到N索引的元素看做是有序的,把N+1索引的元素到最后一个当成是无序的。

遍历无序的数据,将遍历到的元素插入有序序列中适当的位置,如遇到相同数据,插在后面。

N的范围:0~最大索引

public class InsertSort {
    public static void main(String[] args) {
        int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
        myInsertSort(arr);
        myPrint(arr);
    }

    private static void myPrint(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    private static void myInsertSort(int[] arr) {
        if(arr.length <= 1) return;
        for(int i = 1; i < arr.length; ++i){
            // 记录当前要插入的数据索引
            int j = i;
            while(j > 0 && arr[j] < arr[j-1]){
                // 交换位置
                int temp = arr[j];
                arr[j] = arr[j-1];
                arr[j-1] = temp;
                --j;
            }
        }
    }
}
快速排序
递归算法
概述

递归是指方法中调用方法本身的现象

程序书写不当会导致栈溢出, 递归一定要有出口

作用:

  • 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
  • 递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算

递归的两个核心

  • 找出口:什么时候不再调用方法。
  • 找规则 如何把大问题变成规模较小的问题
递归练习

求1-100的和

public class QuickSort {
    public static void main(String[] args) {
        // 求1-100之间的和
        System.out.println(getSum(100));
    }

    public static int getSum(int num){
        // 终止条件 出口
        if(num == 1){
            return 1;
        }
        return num + getSum(num - 1); // 规律
    }
}

求5的阶乘

public static int getJieC(int num){
    if(num == 2) return 2;
    return num * getJieC(num - 1);
}

方法内部再次调用方法的时候, 参数应该比上次更靠近出口

内存图

在这里插入图片描述

快速排序

第一轮: 把0索引的数字作为基准数,确定基准数在数组中正确的位置

比基准数小的全部在左边,比基准数大的全部在右边。

import java.util.Random;

public class QuickSort {
    public static void main(String[] args) {
//        int[] arr = {6,1,2,7,9,3,4,5,10,8};
        int[] arr = new int[1000000];
        Random r = new Random();
        for(int i = 0; i < arr.length; ++i){
            arr[i] = r.nextInt();
        }
        long time1 = System.currentTimeMillis();
        myQuickSort(arr, 0, arr.length - 1);
        long time2 = System.currentTimeMillis();
        //myPrint(arr);
        System.out.println(time2 - time1); // 141
    }

    private static void myPrint(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    private static void myQuickSort(int[] arr, int i, int j) {
        int start = i;
        int end = j;
        if(start >= end) return;
        while(start != end){
            // 用end找到第一个比arr[i]小的数据
            while(start < end && arr[end] >= arr[i]) --end;
            // 用start找到第一个比arr[i]大的数据
            while(start < end && arr[start] <= arr[i]) ++start;

            // 交换start和end的元素
            int temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
        }
        // 此时start和end指向同一元素
        // 即arr[i]应该处于的位置
        int temp = arr[i];
        arr[i] = arr[start];
        arr[start] = temp;

        // 递归排序左边和右边
        myQuickSort(arr, i, start - 1);
        myQuickSort(arr, start + 1, j);
    }

能不能先找start后找end?

不行, 最后基准数归位的时候, 会把一个大于arr[i] 的移动到前面

总结:

1.冒泡排序:
相邻的元素两两比较,小的放前面,大的放后面

2.选择排序:
从0索引开始,拿着每一个索引上的元素跟后面的元素依次比较
小的放前面,大的放后面,以此类推

3.插入排序:
将数组分为有序和无序两组,遍历无序数据,将元素插入有序序列中即可,

  • 4.快速排序
    将排序范围中的第一个数字作为基准数,再定义两个变量start,endstart
  • 从前往后找比基准数大的,end从后往前找比基准数小的。
  • 找到之后交换start和end指向的元素,并循环这一过程,直到start和end处于同一个位置,该位置是基准数在数组中应存入的位置,再让基准数归位。
  • 归位后的效果:基准数左边的,比基准数小,基准数右边的,比基准数大

Arrays

常用方法

没有构造方法

方法基本都是静态的

操作数组的工具类:

在这里插入图片描述

package ArrayTest;

import java.util.ArrayList;
import java.util.Arrays;

public class ArrayDemo1 {
    public static void main(String[] args) {
        test01();
    }

    private static void test01() {
        int[] arr = {1,2,3,4,5};
        System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 5]
        // toString()方法的底层就是用StringBuilder实现拼接的

        int index1 = Arrays.binarySearch(arr, 5); // 二分查找元素
        System.out.println(index1); // 4
        int index2 = Arrays.binarySearch(arr, 10);
        System.out.println(index2); // -6
        // 细节1: 元素需要为升序的
        // 细节2: 元素存在, 返回对应下标
        // 元素不存在的话, 返回其应该插入位置的索引的负数-1
        // 10 应该插入在索引5处, 返回-5-1
        // -1 是因为插入在索引0的时候, -0会给人误导

        int[] arr2 = Arrays.copyOf(arr, 5);
        System.out.println(Arrays.toString(arr2)); // [1, 2, 3, 4, 5]
        // 细节: 第二个参数小于第一个数组的长度是, 会从头截取
        // 等于的话 完全拷贝
        // 大于的话会用初始值填充
        int[] arr3 = Arrays.copyOf(arr, 3);
        System.out.println(Arrays.toString(arr3)); // [1, 2, 3]
        int[] arr4 = Arrays.copyOf(arr, 10);
        System.out.println(Arrays.toString(arr4)); // [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]

        int[] arr5 = Arrays.copyOfRange(arr, 1, 5);
        // 包头不包尾 包左不包右
        System.out.println(Arrays.toString(arr5)); // [2, 3, 4, 5]

        Arrays.fill(arr, 10);
        System.out.println(Arrays.toString(arr)); // [10, 10, 10, 10, 10]
        int[] arr6 = new int[1];
        Arrays.fill(arr6, 100);
        System.out.println(Arrays.toString(arr6)); // [100]
        // 就是说会根据初始数组的长度进行填充
        // 如果数组长度为0, 打印出来就是[]

        int[] arr7 = {3,6,1,9,10,4,8,2,5,7};
        Arrays.sort(arr7);
        System.out.println(Arrays.toString(arr7)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        // 这个方法默认使用快速排序
    }
}
sort方法的重载
package ArrayTest;

import java.util.Arrays;
import java.util.Comparator;

public class SortDemo {
    public static void main(String[] args) {

        // sort参数 要排序的数组  排序规则
        // 细节: 只能给引用数据类型的数组进行排序
        // 如果数组是基本数据类型的, 需要变成其对应的包装类

        Integer[] arr = {3,6,1,9,10,4,8,2,5,7};
        //第二个参数是一个接口,所以我们在调用方法的时候,需要传递这个接口的实现类对象,作为排序的规则。
        //但是这个实现类,我只要使用一次,所以就没有必要单独的去写一个类,直接采取匿名内部类的方式就可以了

        //底层原理:
        //利用插入排序 + 二分查找的方式进行排序的。
        // 默认把0索引的数据当做是有序的序列,1索引到最后认为是无序的序列。
        // 遍历无序的序列得到里面的每一个元素,假设当前遍历得到的元素是A元素
        // 把A往有序序列中进行插入,在插入的时候,是利用三分查找确定A元素的插入点。
        // 拿着A元素,跟插入点的元素进行比较,比较的规则就是compare方法的方法体
        // 如果方法的返回值是负数,拿着A继续跟前面的数据进行比较
        // 如果方法的返回值是正数,拿着A继续跟后面的数揭进行比较
        // 如果方法的返回值是e,也拿着A跟后面的数据进行比较
        // 直到能确定A的最终位置为止。

        // compare方法的形式参数:
        // 参数1: o1 表示在无序序列中, 遍历得到的每一个元素
        // 参数2: o2 表示有序序列的元素

        //返回值
        //负数: 表示当前要插入的元素是小的,放在前面
        //正数: 表示当前要插入的元素是大的,放在后面
        //0: 表示当前要插入的元素跟现在的元素比是一样的们也会放在后面
        Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // return o1 - o2;// 升序排序
                return  o2 - o1; // 降序排序
            }
        });

        System.out.println(Arrays.toString(arr));

    }
}

Lambda表达式

用lambda表达式对sort进行简化

函数式编程

是一种思想特点, 忽略面向对象的复杂语法, 强调做什么, 而不是谁去做

面向对象: 先找对象, 让对象做事情

Lambda表达式的标准格式

package LambdaTest;

import java.util.Arrays;

public class LambdaDemo {
    public static void main(String[] args) {
        sortByLambda();

    }

    private static void sortByLambda() {
        Integer[] arr = {9,3,6,1,4,10,7,2,8,5};
        Arrays.sort(arr, (Integer a, Integer b) -> {
                    return b - a;
        });
        System.out.println(Arrays.toString(arr));
    }
}

注意点:

  • Lambda表达式可以用来简化匿名内部类的书写
  • Lambda表达式只能简化函数式接口的匿名内部类的写法
  • 函数式接口:

有且仅有一个抽象方法的接口叫做函数式接口接口上方可以加@Functionallnterface注解

package LambdaTest;

public class LambdaDemo2 {
    public static void main(String[] args) {
        // 利用匿名内部类
        // 调用一个方法的时候, 如果方法的形参是一个接口, 那么要传递这个接口的实现类对象
        // 如果实现类对象只要用到一次, 就可以用匿名内部类的形式进行书写
//        method(new Swim() {
//            @Override
//            public void swim() {
//                System.out.println("swiming");
//            }
//        });

        // lambda表达式
        method(()->{
            System.out.println("swiming");
        });
    }

    private static void method(Swim s) {
        s.swim();
    }
}

@FunctionalInterface
interface Swim{
    abstract void swim();
}

小结:

lambda基本作用: 简化函数式接口匿名内部类的写法

使用前提: 必须是接口的匿名内部类, 接口中只能有一个抽象方法

好处: 简化代码

Lambda表达式的省略写法

省略核心: 可推导, 可省略

省略规则:

  1. 参数类型可以省略不写
  2. 如果只有一个参数, 参数类型可以省略, 同时() 也可以省略
  3. 如果Lambda表达式的方法体只有一行, 大括号, 分号, return可以省略不写, 需要同时省略
package LambdaTest;

import java.util.Arrays;

public class LambdaDemo {
    public static void main(String[] args) {
        sortByLambda();
    }

    private static void sortByLambda() {
        Integer[] arr = {9,3,6,1,4,10,7,2,8,5};
        Arrays.sort(arr, (a,  b) -> b - a);
        System.out.println(Arrays.toString(arr));
    }
}

练习:

定义数组并存储一些字符串,利用Arrays中的sort方法进行排序
要求:
按照字符串的长度进行排序,长的在前面,短的在后面(暂时不比较字符串里面的内容)

package LambdaTest;

import java.util.Arrays;

public class LambdaDemo3 {
    public static void main(String[] args) {
        String[] arr = {"asd", "q", "fdsfe", "vfrfsa", "vc", "hjgy"};
        Arrays.sort(arr, (String s1, String s2) -> s2.length() - s1.length());
        System.out.println(Arrays.toString(arr)); // [vfrfsa, fdsfe, hjgy, asd, vc, q]
    }
}

综合练习

练习1

定义数组并存储一些女朋友对象,利用Arrays中的sort方法进行排序
要求1:属性有姓名、年龄、身高。
要求2:按照年龄的大小进行排序,年龄一样,按照身高排序,身高一样按照姓名的字母进行排序.(姓名中不要有中文或特殊字符,会涉及到后面的知识)

JavaBean类

package Practice;

public class GirlFriend {
    private String name;
    private int age;
    private int height;

    public GirlFriend() {
    }

    public GirlFriend(String name, int age, int height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "GirlFriend{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }
}

测试类:

package Practice;

import java.util.Arrays;

public class Test01 {
    public static void main(String[] args) {
        GirlFriend g1 = new GirlFriend("qwe", 20, 168);
        GirlFriend g2 = new GirlFriend("efhgtg", 18, 173);
        GirlFriend g3 = new GirlFriend("tyghh", 22, 170);
        GirlFriend g4 = new GirlFriend("rtgfd", 18, 169);
        GirlFriend g5 = new GirlFriend("vfdgt", 20, 168);

        // System.out.println(g1);

        GirlFriend[] arr = {g1, g2, g3, g4, g5};
//        for (int i = 0; i < arr.length; i++) {
//            System.out.println(arr[i]);
//        }

//        按照年龄的大小进行排序,年龄一样,按照身高排序,
//        身高一样按照姓名的字母进行排序
        // 年龄升序 升高降序 名字字典升序
        Arrays.sort(arr, (g01,  g02) -> {
            if(g01.getAge() == g02.getAge() && g01.getHeight() == g02.getHeight()){
                return g01.getName().compareTo(g02.getName());
            } else if (g01.getAge() == g02.getAge()) {
                return g02.getHeight() - g01.getHeight();
            }else {
                return g01.getAge() - g02.getAge();
            }
        });

        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}
练习2

有一个很有名的数学逻辑题叫做不死神兔问题,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第十二个月的兔子对数为多少?

package Practice;

public class Test02 {
    public static void main(String[] args) {
        int month = 12;
        int res = getSum(month);
        System.out.println(res);
    }

    private static int getSum(int month) {
        if(month == 1 || month == 2) return 1;
        return getSum(month - 1) + getSum(month - 2);
    }
}
练习3

有一堆桃子,猴子第一天吃了其中的一半,并多吃了一个!以后每天猴子都吃当前剩下来的一半,然后再多吃一个,第10天的时候(还没吃),发现只剩下一个桃子了,请问,最初总共多少个桃子?

package Practice;

public class Test03 {
    public static void main(String[] args) {
        int num = 10;
        int res = getSum(num);
        System.out.println(res);
    }

    private static int getSum(int num) {
        if(num == 1) return 1;
        return (getSum(num-1) + 1) * 2;
    }
}
练习4

可爱的小明特别喜欢爬楼梯,他有的时候一次爬一个台阶,有的时候一次爬两个台阶。
如果这个楼梯有20个台阶,小明一共有多少种爬法呢?
运算结果:
1层台阶1种爬法
2层台阶2种爬法
7层台阶 21种爬法

package Practice;

public class Test04 {
    public static void main(String[] args) {
        int num = 20;
        int res = getSum(num);
        System.out.println(res);
    }

    private static int getSum(int num) {
        if(num == 1) return 1;
        if(num == 2) return 2;
        return getSum(num - 1) + getSum(num - 2);
    }
}

扩展: 还可以爬三层(动态规划做法)

package Practice;

public class Test05 {
    public static void main(String[] args) {
        int num = 20;
        int res = getSum(num);
        System.out.println(res);
    }

    private static int getSum(int num) {
        if (num == 1) return 1;
        if (num == 2) return 2;
        if (num == 3) return 4;

        int[] dp = new int[num + 1];
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 4;

        for (int i = 4; i <= num; i++) {
            dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
        }

        return dp[num];
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1270708.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第二证券:机构争分夺秒抢滩 金融大模型落地为时尚早

本年以来&#xff0c;大模型席卷金融业&#xff0c;一夜之间&#xff0c;简直悉数金融场景都在探索适配大模型接口。但是&#xff0c;志向丰满&#xff0c;实践骨感。有大型金融组织IT部分人士比方&#xff0c;金融大模型从战略规划到安顿落地&#xff0c;有着从“卖家秀”走到…

Docker 下载加速

文章目录 方式1&#xff1a;使用 网易数帆容器镜像仓库进行下载。方式2&#xff1a;配置阿里云加速。方式3&#xff1a;方式4&#xff1a;结尾注意 Docker下载加速的原理是&#xff0c;在拉取镜像时使用一个国内的镜像站点&#xff0c;该站点已经缓存了各个版本的官方 Docker 镜…

两台电脑如何快速传输几百G文件,这款文件传输软件真快

当我们需要传输数百GB的文件时&#xff0c;使用传统工具对于大型文件传输来说往往效率低下。这些方法可能需要数小时&#xff0c;甚至数天才能完成传输。然而&#xff0c;现代生活和工作中&#xff0c;我们经常需要以更快速、更高效的方式传输大文件&#xff0c;无论是因为工作…

连锁零售企业如何提高异地组网的稳定性?

随着数字化时代的到来&#xff0c;连锁零售企业面临着日益复杂和多样化的网络挑战。连锁零售企业是在不同地理位置拥有分支机构和零售店&#xff0c;可能同城或异地&#xff0c;需要确保各个地点之间的网络连接稳定和可靠。但由于不同地区的网络基础设施差异、网络延迟和带宽限…

应用密码学期末复习(3)

目录 第三章 现代密码学应用案例 3.1安全电子邮件方案 3.1.1 PGP产生的背景 3.2 PGP提供了一个安全电子邮件解决方案 3.2.1 PGP加密流程 3.2.2 PGP解密流程 3.2.3 PGP整合了对称加密和公钥加密的方案 3.3 PGP数字签名和Hash函数 3.4 公钥分发与认证——去中心化模型 …

【小布_ORACLE笔记】Part11-5 RMAN Backups

【小布_ORACLE笔记】Part11-5 RMAN Backups 文章目录 【小布_ORACLE笔记】Part11-5 RMAN Backups1. 增量备份&#xff08;Incremental Backups)1.1差异增量备份&#xff08;Differential Incremental Backup&#xff09;1.2累积增量备份&#xff08;Cumulative Incremental Bac…

跨界融合,科技耕耘:MTX基金公司与ICG共塑全球农业科技新景观

在全球经济快速发展的当下&#xff0c;农业科技创新成为了社会进步的重要推动力。MTX基金公司对ICG的投资是在这一背景下的战略决策&#xff0c;不仅寻求经济效益&#xff0c;更承载着改善全球农业生产、实现食品安全与环境保护的使命。 1、战略投资&#xff1a;文化情怀与全球…

Python三十个常见的脚本汇总

1、冒泡排序 2、计算x的n次方的方法 3、计算a*a b*b c*c …… 4、计算阶乘 n! 5、列出当前目录下的所有文件和目录名 6、把一个list中所有的字符串变成小写&#xff1a; 7、输出某个路径下的所有文件和文件夹的路径 8、输出某个路径及其子目录下的所有文件路径 9、输出某个路…

【刷题笔记】长度最小的子数组||二分查找||边界||数组

长度最小的子数组 1 题目描述 https://leetcode.cn/problems/minimum-size-subarray-sum/ 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl1, …, numsr-1, numsr] &#xff0c;并返回…

如何用管理项目的方式管理个人任务

同样一份工作&#xff0c;有的人做起来得心应手&#xff0c;条理清晰&#xff0c;有的人却是手忙脚乱&#xff0c;苦不堪言。在凡事皆项目的时代&#xff0c;用管理项目的方法管理自己的任务&#xff0c;可能会让你的工作事半功倍。 工欲善其事&#xff0c;必先利其器&#xf…

webshell之API免杀

ScriptEngineManager命令执行免杀 ScriptEngineManager执行js代码 利用ScriptEngineManager可以执行js命令&#xff0c;但是由于一般情况下&#xff0c;即便能运行js代码也不一定能执行系统命令。因为一般情况下js执行系统命令主要是依靠两种方式&#xff0c;IE的ActiveX插件…

「幻醒蓝」可视化主题套件|融合天空的清澈与海洋的深邃

现如今&#xff0c;数据可视化已成为信息传递的重要手段之一。在这样一个信息爆炸的时代&#xff0c;向人们传达正确的信息显得尤为重要。为此&#xff0c;可视化主题套件应运而生&#xff0c;提供了一种多样化的、可视化的方式来展示数据。不同的主题套件能够适应不同的信息传…

Springboot如何快速生成分页展示以及统计条数

这是表结构&#xff1a; 前置知识&#xff1a; 分页查询公式&#xff08;&#xff09;&#xff1a; -- 推导一个公式 -- select * from emp -- order by empno -- limit 每页显示记录数 * (第几页-1)&#xff0c;每页显示记录数 统计条数公式&#xff1a; select count…

力扣5.最长回文子串

题目描述 思路 1.能够反复利用已判断好的回文子串 2.当子串s[i1,j-1]是回文子串时&#xff0c;只要s[i]s[j]&#xff0c;那么s[i,j]也会是回文子串 3.用好动态规划&#xff0c;具体解释在代码注释里 代码 class Solution {public String longestPalindrome(String s) {int…

【网络安全】meterpreter攻击实战

1.meterpreter 攻击成功后可以做什么指令&#xff1f; 远程控制命令执行摄像头监控密码获取创建后门用户破坏篡改系统。 2.创建后门用户并开启远程连接&#xff1a; net user zhangsan 123456/add && net localgroup adminstrators zhangsan/add exit run getgul -…

Linux 代码编辑器:vim

vim 编辑器的简介 vi / vim 都是多模式编辑器&#xff0c;不同的是 vim 是 vi 的升级版本&#xff0c;他不仅兼容 vi 的所有指令&#xff0c;而且还有一些新的特性在里面。比如语法高亮&#xff0c;可视化操作不仅可以在终端运行&#xff0c;也可以在 windows&#xff0c;mac …

聊一聊大模型 | 京东云技术团队

事情还得从ChatGPT说起。 2022年12月OpenAI发布了自然语言生成模型ChatGPT&#xff0c;一个可以基于用户输入文本自动生成回答的人工智能体。它有着赶超人类的自然对话程度以及逆天的学识。一时间引爆了整个人工智能界&#xff0c;各大巨头也纷纷跟进发布了自家的大模型&#…

【算法】算法题-20231129

这里写目录标题 一、15. 三数之和二、205. 同构字符串三、383. 赎金信 一、15. 三数之和 提示 中等 6.5K 相关企业 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] …

leetcode 18. 四数之和(优质解法)

代码&#xff1a; class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> listsnew ArrayList<>();int lengthnums.length;Arrays.sort(nums);for(int i0;i<length-4;){for(int ji1;j<lengt…

Oracle--索引

文章目录 一、索引是什么?二、索引的原理三、索引的特征四、创建索引的方式五、怎么确认索引六、案列七、复合索引 一、索引是什么? 索引&#xff08;INDEX&#xff09;是数据库中用于提高查询效率的一种数据结构。它可以加速数据库表的数据查找、过滤和排序等操作。索引是一…