[算法与数据结构]--贪心算法初识

news2024/11/26 18:18:59

贪心算法

  • 贪心算法的解题过程
  • 贪心算法案例
    • 1.选择排序
    • 2. 平衡字符串
    • 3. 买卖股票的最佳时机 II
    • 4. 跳跃游戏
    • 5 钱币找零
    • 6 多机调度问题
    • 7.活动选择
    • 8. 最多可以参加的会议数目
    • 9. 无重叠区间

来自算法导论对于这个贪心算法的解释定义

在这里插入图片描述

贪心算法(又名贪婪算法)故名思意就是一个“贪心”的算法。把一个问题拆分成子问题,贪心算法只顾子问题的最优解,不考虑问题的整体,只考虑当下,这就是所谓的贪心。

贪心算法的解题过程

  1. 建立数学模型
  2. 把求解的问题拆分成若干个若子问题;
  3. 对每一子问题求解最优解;
  4. 把子问题的最优解合并成该问题的解

该算法只能满足约束条件下可行范围的解,最终解不一定是这个问题的最优解。

贪心算法案例

1.选择排序

选择排序(排升序)是在数据结构学习中学到的几个排序算法之一,该排序算法只考虑在未排序范围内的最小值放在前面,最后未排序范围变成了0,排序算法终止。这个只考虑部分最小,不考虑总体这个就是贪心思想。

	public static void main(String[] args) {
        int[] arr = {9,8,4,6,2,5};
        selectSort(arr);
        System.out.println(Arrays.toString(arr));

    }
    private static void selectSort(int[] arr) {
        //从下标0开始一直缩小未排序数据的范围,
        for (int i = 0; i < arr.length; i++) {
            //找到未排序数据中的最小值的索引。
            int min = i;
            for (int j = i; j < arr.length; j++) {
                if (arr[j] < arr[min]){
                    min = j;
                }
            }
            //最小值和未排序数据最小下标的值进行互换
            swap(arr,min,i);
        }
    }

    private static void swap(int[] arr, int min, int i) {
        int tmp = arr[min];
        arr[min] = arr[i];
        arr[i] = tmp;
    }

2. 平衡字符串

原题链接

✨问题描述:
平衡字符串 中,‘L’ 和 ‘R’ 字符的数量是相同的。
给你一个平衡字符串 s,请你将它分割成尽可能多的子字符串,并满足:
每个子字符串都是平衡字符串。
返回可以通过分割得到的平衡字符串的 最大数量 。

✨案例:

输入:s = “RLRRLLRLRL” 输出:4 解释:s 可以分割为 “RL”、“RRLL”、“RL”、“RL”
,每个子字符串中都包含相同数量的 ‘L’ 和 ‘R’ 。

✨题目分析:
该题目是分割成一个一个的平衡字符串,要求平衡字符串的个数最多。
根据案例1来说:我们如果找到了一个平衡子串,RL但是我们还要往后进行不重新找,找到RLLRRLL,剩下的字符串最多只能找到两个平衡串。所以我们不能够让子串串嵌套。只要找到一个平衡字串就重新找字串。这是一个很明显的贪心算法思想
所以贪心思想:不能够让字串嵌套。
我们可以定义一个计数变量count来记录平衡串的个数,
判断平衡串:可以定义变量balance,如果是R进行+1,如果是L进行-1.什么时候balance == 0,就说明该子串为平衡串。

✨实现代码:

class Solution {
    public int balancedStringSplit(String s) {
        int balance = 0;
        int count = 0;
        for(int i = 0;i < s.length();i++){
            if(s.charAt(i) == 'R'){
                balance++;
            }else if(s.charAt(i) == 'L'){
                balance--;
            }
            if(balance == 0){
                count++;
            }
        }
        return count;
    }
}

3. 买卖股票的最佳时机 II

原题链接
✨题目描述:
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
✨案例:

输入:prices = [7,1,5,3,6,4] 输出:7 解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 =
5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
总利润为 4 + 3 = 7 。

输入:prices = [1,2,3,4,5] 输出:4 解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 => 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。 总利润为 4 。

✨题目分析:
该题目属于一个马后炮分析股票,我们在买股票的时候怎么会知道该股票第二天是涨还是跌呢。我们在做这个题目的时候就在股票上升阶段我们在第一题卖入,明天要下跌了我么就把股票给卖出去。在股票下跌阶段我们不进行任何的一个操纵。此种操作才会使我们的这个股票收益最大。
现在我们的难题就是对上升阶段进行操作,如何在上升阶段的最后一天把股票卖了,如果我们只考虑起始时间和终止时间我们会把最后一天分成两种情况是否是股票交易的最后一天还仅仅是股票上涨的最后一天。这种明显就比较复杂。我们可以考虑贪心思想,只考虑局部不考虑整体,比如只要是明天股票上升我今天就买,明天就买。这种和上升阶段的最后一天 - 上升阶段的第一天 得到的数值是相同的。
贪心思想:只要是明天上升我今天就买明天卖。只要是下降我就不进行任何操作。

✨代码实现:

class Solution {
    public int maxProfit(int[] prices) {
        int money = 0;
        for(int i = 1;i < prices.length;i++){
            if(prices[i] > prices[i - 1]){
                money += prices[i] - prices[i-1];
            }
        }
        return money;
    }
}

✨其他思路:
这个问题还可以用动态规划来进行解决。我们可以定义一个二维数组dp[i][j]。i 代表天数,j代表改天持有股票还是持有现金。j == 0 是持有现金。 j == 1 就是持有股票。一天只有这两种状态。这一天持有现金是可能昨天持有现金今天没有任何操作,还有一种可能就是昨天持有股票今天把股票给卖了。这一天持有股票肯能是前一天有股票今天没买,也有可能是昨天没有股票,今天买了。

  • 装填转移:
    dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] + prices) //前者昨天没股票今天没进行操作。后者是昨天买了股票今天把股票买了。取两者最大值。
    dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0] - prices)//前者是昨天的股票今天没有进行任何操作。后者是昨天没有股票今天买了股票。两者取最大值。
  • 初始状态:
    dp[0][0] = 0;//第一天没有买股票
    dp[0][1] = -7; // 第一天持有股票现有现金为 -7.
  • 返回结果:
    return dp[prices.length - 1][0];//肯定是最后一天把股票卖出去了,手里的现金最多。
    就案例一来进行画图解析
    在这里插入图片描述

代码:

class Solution {
    public int maxProfit(int[] prices) {
        int len = prices.length;
        int[][] dp = new int[len][2];
        //进行初始化
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        //进行状态转移
        for(int i = 1;i < len;i++){
            dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] + prices[i]);//没有股票
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0] - prices[i]);//持有股票
        }
        return dp[len - 1][0];
    }
}

当然这个动态规划可以进一步的简化,但是是比贪心算法要复杂,所以这个题用动态规划属于是杀鸡用来宰牛刀。

4. 跳跃游戏

原题链接

✨题目描述:
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
✨案例:

输入:nums = [2,3,1,1,4] 输出:true 解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3
步到达最后一个下标。

输入:nums = [3,2,1,0,4] 输出:false 解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 ,
所以永远不可能到达最后一个下标。

✨题目分析

设想一下,对于数组中的任意一个位置 y,我们如何判断它是否可以到达?根据题目的描述,只要存在一个位置x,它本身可以到达,并且它跳跃的最大长度为 x + nums[x],这个值大于等于 y,即 x+nums[x] ≥ y,那么位置y也可以到达。换句话说,对于每一个可以到达的位置 x,它使得 x+1, x+2,⋯,x+nums[x] 这些连续的位置都可以到达。 这样以来,我们依次遍历数组中的每一个位置,并实时维护最远可以到达的位置。
对于当前遍历到的位置x,如果它在最远可以到达的位置的范围内,那么我们就可以从起点通过若干次跳跃到达该位置,因此我们可以用 x+nums[x]更新 最远可以到达的位置。
在遍历的过程中,如果最远可以到达的位置大于等于数组中的最后一个位置,那就说明最后一个位置可达,我们就可以直接返回True作为答案。反之,如果在遍历结束后,最后一个位置仍然不可达,我们就返回
False 作为答案。

就以案例1来说,0下标最远可以到达2下标,1下标最远可以到达4下标,4下标就是最后一个位置,
案例2进行分析:0下标最远可以到达3下标,1下标最远可以到达3下标,2下标最远可以到达3下标,3位置最远可以到达3下标,但是4下标就不能能够到达了。
我们可以遍历数组然后用max记录能到达的最远位置,就是用max和该x+nums[x],记录最大值。如果在中间某个位置跳跃的位置包含,我们就可以返回true了。如果中间某个位置跳跃不到或者我们循环结束到打不了最后位置我们就返回false。
贪心思想:站在每一个位置,更新可以到达的最远位置。
✨ 题目代码

class Solution {
    public boolean canJump(int[] nums) {
        int max = 0;
        int pos = nums.length - 1;
        //遍历数组记录能到达的最远值
        for(int i = 0;i <= pos;i++){
            if(max >= i){//能到达该位置
                max = Math.max(max,nums[i] + i);
                if(max >= pos){//能跳跃到的最远距离包含了目标位置
                    return true;
                }
            }else{
                return false;
            }
        }
        return false;
    }
}

5 钱币找零

✨ 问题描述
假设1元、2元、5元、10元、20元、50元、100元的纸币分别有c0, c1, c2, c3, c4, c5, c6张。现在要用这些钱来支付K元,至少要用多少张纸币?
✨初始条件

    public static void main(String[] args) {
        int[][] moneyCount = { { 1, 3 }, { 2, 1 }, { 5, 4 }, { 10, 3 }, { 20, 0 }  ,{50, 1}, { 100, 10 } };
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要支付的钱");
        int count = maxNum(scanner.nextInt(), moneyCount);//通过maxNum方法计算出最小张数量
        if (count == -1){
            System.out.println("No");
        }else {
            System.out.println("最小张数" + count);
        }

✨贪心思想
我们要想求最少张数,应该从先面值大的钱开始计算,然后再计算面值小的钱
✨题目代码

    private static int maxNum(int money, int[][] moneyCount) {
        int count = 0;//记录当前花费钞票的张数
        for (int i = moneyCount.length - 1; i >= 0; i--) {
            int num = Math.min(money / moneyCount[i][0],moneyCount[i][1]);
            count += num;
            money -= num * moneyCount[i][0];
        }
        if (money == 0){
           return count;
        }
        return -1;
    }

6 多机调度问题

✨ 问题描述
某工厂有n个独立的作业,由m台相同的机器进行加工处理。作业i所需的加工时间为ti,任何作业在被处理时不能中断,也不能进行拆分处理。现厂长请你给他写一个程序:算出n个作业由m台机器加工处理的最短时间
输入
第一行T(1<T<100)表示有T组测试数据。每组测试数据的第一行分别是整数n,m(1<=n<=10000,1<=m<=100),接下来的一行是n个整数ti(1<=t<=100)。
输出

✨案例

n =6 m =3 ti :13 15 16 2 5 20
输出结果:28

✨ 问题分析
我们针对这个问题没有最有最优解,但是可以用贪心算法来求次优解。我们再做这个问题时候,如果m >= n的话,我们的机器就一次性的把任务都并发处理,我们直接找这几个作业的最大值就行了。 如果m < n 时,我们不能随便把数据放到机器上,我们随机放的话可能会造成一个机器时间特别长,一个机器时间特别短不能够充分利用,如果我们先处理时间短的,会发生时间短的任务处理完了,剩下的时间长的,所以我们的任务就是优先处理时间长的,机器上哪个先处理完,我们们就把没有处理的数据时间长的放进去,如此往复处理完所有的作业,哪个机器最后处理完就是我们所需要的最短时间。
贪心思想:每次取剩余作业时间最长的,分配给最先结束的机器。

画图分析:
在这里插入图片描述

✨题目代码

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int[] taskTime = new int[n];
        for (int i = 0; i < n; i++) {
            taskTime[i] = scanner.nextInt();
        }
        int num = greedStrategy(m,taskTime);
        System.out.println("处理的最短时间" + num);
    }

    private static int  greedStrategy(int m , int[] array) {
        Arrays.sort(array);//进行升序排序
        int n = array.length;
        if(n <= m){//作业数小于等于机器数
            return array[n-1];
        }
        //作业数大于机器数
        int[] machines = new int[m];
        for (int i = array.length - 1; i >= 0; i--) {
            //寻找machines中最下值的下标,也就是分配任务最先结束的机器
            int min = 0;
            for (int j = 0; j < m; j++) {
                if (machines[min] > machines[j]) {
                    min = j;
                }
            }
            //最先处理完的机器 + 一个任务
            machines[min] += array[i];
        }
        return findMax(machines);
    }

    private static int findMax(int[] machines) {
       int max = machines[0];
        for (int i = 1; i < machines.length; i++) {
            if (max < machines[i]){
                max = machines[i];
            }
        }
        return max;
    }


7.活动选择

✨ 问题描述:有n个需要在同一天使用同一个教室的活动a1, a2, …, an,教室同一时刻只能由一个活动使用。每个活动a[i]都有一个开始时间s[i]和结束时间f[i]。一旦被选择后,活动a[i]就占据半开时间区间[s[i],f[i])。如果[s[i],f[i])和[s[j],f[j])互不重叠,a[i]和a[j]两个活动就可以被安排在这一天。求使得尽量多的活动能不冲突的举行的最大数量。

✨案例:

int[][] events = {{2,5},{3,4},{1,6},{5,8},{5,7},{3,9},{7,10}};
输出结果:3

✨贪心思想:

我们经过了上面的几个题目,有按着时间短的先安排的:
在这里插入图片描述

按着上面的样例来说,选择了5 – 8 点,剩下的两个时间段就不能再选了。剩下两个时间段可以同时选择。所以说时间最短这个思路是不能够实时的。


我们安排对开始时间最短进行优先选择的话:
在这里插入图片描述
像上图这种情况就是选择开始时间早来进行优先选择的,很明显不可以这样安排。


我们可以用结束时间进行排序:
  1. 按着结束时间早的开始进行升序排序(结束时间早也就间接说明了活动举办时间相对较少)。为没有举行的活动留下更多的时间。
  2. 初始:在结束时间最早的活动如果有相同的结束时间,在活动任找一个活动举行,作为第一个活动
  3. 在剩下的一些活动中,找开始时间大于前者的结束时间的一个活动作为下一个活动。

这样能够保证我们每天安排的活动数量是最多的。

  • 这样我们就可以把活动进行一个以结束时间为升序,如果结束时间相同则开始时间为升序进行排序。然后进行查找当天能够最多举行的活动的数目

画图解析:在这里插入图片描述

✨题目代码

public static void main(String[] args) {
        int[][] events = {{2,5},{3,4},{1,6},{5,8},{5,7},{3,9},{7,10}};
        int max = getMax(events);
        System.out.println(max);
    }

    private static int getMax(int[][] events) {
        //进行以结束时间为主,开始时间为辅的升序排序。
        Arrays.sort(events,(int[] arr1,int[] arr2)->  { return arr1[1] - arr2[1] == 0 ? arr1[0] - arr2[0]:arr1[1] - arr2[1];});
        int count = 1;
        int cur = 0;
        for (int i = 1; i < events.length; i++) {
            if (events[i][0] >= events[cur][1]){
                count++;
                cur = i;
            }
        }
        return count;
    }

8. 最多可以参加的会议数目

原题链接
✨ 问题描述:
给你一个数组 events,其中 events[i] = [startDayi, endDayi] ,表示会议 i 开始于 startDayi ,结束于 endDayi 。你可以在满足 startDayi <= d <= endDayi 中的任意一天 d 参加会议 i 。注意,一天只能参加一个会议。
请你返回你可以参加的 最大 会议数目。

✨案例:
在这里插入图片描述
案例1:
输入:events = [[1,2],[2,3],[3,4]]
输出:3
解释:你可以参加所有的三个会议。
安排会议的一种方案如上图。
第 1 天参加第一个会议。
第 2 天参加第二个会议。
第 3 天参加第三个会议。


案例2:
输入:events = [[1,4],[4,4],[2,2],[3,4],[1,1]]
输出:4

✨题目分析:

这个问题和第七题的思想有一定的差别,第七题是用结束时间升序进行安排活动举行。但是这个问题就不能用结束时间升序来进行解决了的。
就比如案例2来说。在这里插入图片描述
所以我们不能够对结束时间进行升序排序,但是我们对开始时间进行升序排序的话,这个问题就能解决了。
在这里插入图片描述
对于上面的结束时间早的先执行,我们可以用优先级队列存储结束时间。把开始时间大于等于想要安排会议当天,我们就可以把他们的结束时间存储到优先级队列中。再进行计算过程中,如果优先级队列中的队头元素小于当前天,这些是结束时间小于当前天了,也就是说不能够执行的会议,我们就把他的结束时间从优先级队列中去除掉

✨题目代码

    public int maxEvents(int[][] events) {
        //以开始时间为升序进行排序
        Arrays.sort(events,(int[] arr1,int[] arr2)-> {return arr1[0] - arr2[0];});
        PriorityQueue<Integer> pq = new PriorityQueue<>();//存放结束时间的优先级队列
        int count = 0;//记录可以安排的活动数量
        int i = 0;//遍历活动数组的下标
        int day = 0;//判断每一天是否可以参加会议,是第几天。
        while (!pq.isEmpty() || i < events.length){
            while (i < events.length && day == events[i][0]){//对相同起始时间的会议加入到优先级队列中
                pq.offer(events[i][1]);
                i++;
            }
            while (!pq.isEmpty() && day > pq.peek()){//删除结束时间小于当前天数的活动,也就是说删除不能够举行的会议
                pq.poll();
            }
            if (!pq.isEmpty() && day <= pq.peek()){//对结束时间最小的会议进行分配时间
                pq.poll();
                count++;
            }
            day++;
        }
        return count;
    }

9. 无重叠区间

原题链接

✨ 问题描述:

给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。

✨案例:
案例1
输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。

案例2:
输入: intervals = [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。

案例3:
输入: intervals = [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。

✨题目分析:

该问题其实有两种思路:
第一种是可以借助题目7的思想,题目7是活动的选择,活动的选择是找无重叠的最大活动数。我们只需要求出无重叠的最大数量,然后用总小区间的个数 - 无重叠区间的最大个数,就可以求出来移除区间的最小值。
第二种思路就是直接求出需要移除的区间的额个数。我们可以按着起始时间进行升序排序,然后对重叠部分进行取舍。区间重叠无非就以下两种情况:
在这里插入图片描述

我们升序排序后,我们遍历数组进行判断操作。我们只需要对最新区间的结束位置进行记录,发生重叠,就把结束位置更新为暂时并不需要被移除的最后一个的结束位置。

✨题目代码

方案1:

    public int eraseOverlapIntervals(int[][] intervals) {
        Arrays.sort(intervals,(int[] arr1,int[] arr2)-> arr1[1] - arr2[1] );//对区间结束位置进行升序排序
        int count = 1;//记录不需要被移除的区间数量。
        int end = intervals[0][1];//结束时间早的区间结束位置
        for (int i = 1; i < intervals.length; i++) {
            if (end <= intervals[i][0]){
                count++;
                end = intervals[i][1];
            }
        }
        return intervals.length - count;
    }

方案2:

    public int eraseOverlapIntervals(int[][] intervals) {
        int count = 0;//移除区间的个数
        Arrays.sort(intervals,(int[] arr1,int[] arr2)-> arr1[0] - arr2[0]);//把区间数组按起始位置进行升序排列。
        int end = intervals[0][1];
        for (int i = 1; i < intervals.length; i++) {
            if (intervals[i][1] < end) {//区间重叠情况1:删除前者。
                end = intervals[i][1];
                count++;
            } else if (intervals[i][0] < end){//重区间叠情况2,删除后者。
                count++;
            }else{//不重叠情况
                end = intervals[i][1];
            }
        }
        return count;

    }

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

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

相关文章

小程序开发(一)新建/拉取项目,配置远程仓库

一、前期准备工作及工具 1、工具 微信开发者工具、Git 2、准备工作 相关开发工具的安装和配置工作请自行百度 二、新建或拉取远程项目 1、打开微信开发者工具(扫码登录等验证工作自行操作)&#xff0c;选择小程序。 2、点击号新建项目&#xff0c;项目名称、目录、模板选…

Git(狂神课堂笔记)

1.首先去git官网下载我们对应的版本Git - Downloading Package (git-scm.com) 2.安装后我们会发现git文件夹里有三个应用程序&#xff1a; Git Bash&#xff1a;Unix与Linux风格的命令行&#xff0c;使用最多&#xff0c;推荐最多 Git CMD&#xff1a;Windows风格的命令行 G…

kafka入门到实战三(单线程实现顺序消费,含demo)

这里需要前面两章的基础&#xff0c;如果没有环境或者看不懂在说什么&#xff0c;就翻一翻前两章。 kafka顺序消费&#xff08;单线程&#xff09; 顺序消费 顺序消费&#xff1a;是指消息的产生顺序和消费顺序相同。不管你用的是什么q或者kafka还是sofa&#xff0c;顺序依赖…

启动框架 Anchors接入和分析

参考:https://juejin.cn/post/6844904128443858958https://blog.csdn.net/gqg_guan/article/details/127760207从哪下手整个冷启动过程中&#xff0c;系统方法我们无法进行优化&#xff0c;主要需要优化的是系统暴露出来的一些生命周期方法&#xff0c;从Application的attachBa…

OSCP学习踩过的坑

OSCP终于拿到证&#xff0c;感觉参加考试备考的日子才过去没有多久&#xff0c;想起了那几个月被“虐待”的日子&#xff0c;我想总结下在课程和考试中的犯的错误&#xff01; 计划 我制定了一个学习计划&#xff0c;计划是学习、练习&#xff0c;然后再学习、练习一些&#…

SpringCloud:服务拆分及远程调用

目录 SpringCloud&#xff1a;服务拆分及远程调用 1、服务拆分 2、远程调用 SpringCloud&#xff1a;服务拆分及远程调用 SpringCloud是目前国内使用最广泛的微服务框架。 官网地址: Spring Cloud SpringCloud集成了各种微服务功能组件&#xff0c;并基于SpringBoot实现了…

【10】SCI易中期刊推荐——工程技术-计算机:人工智能(中科院2区)

🚀🚀🚀NEW!!!SCI易中期刊推荐栏目来啦 ~ 📚🍀 SCI即《科学引文索引》(Science Citation Index, SCI),是1961年由美国科学信息研究所(Institute for Scientific Information, ISI)创办的文献检索工具,创始人是美国著名情报专家尤金加菲尔德(Eugene Garfield…

JAVA开发(Eureka基本原理)

Eureka基本原理。 通过上图我们可以看出&#xff0c;服务提供者在启动的时候需要向注册中心注册自己的信息&#xff0c;而注册中心把向自己注册的服务提供者都保存下来&#xff0c;以便服务消费者获取用来发起请求&#xff0c;而服务消费者需要从注册中心获取服务提供者列表&am…

网络层:IP协议

目录 基本概念 IP报头 IP报文分片 为什么要分片&#xff1f; 如何分片&#xff1f; 分片的报文如何组装&#xff1f; 分片策略如何&#xff1f; 网段划分 IP地址被分成了五类IP&#xff1a; CIDR 特殊的IP地址&#xff1a; 私有IP和公网IP 路由 如何转发数据包&a…

「ABAP」一文带你入门OPEN SQL中的SELECT查询(附超详细案例解析)

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后…

阿里云服务器价格,阿里云轻量应用服务器最新价格表

阿里云服务器从地域上来区分可分为ECS云服务器和轻量应用服务器&#xff0c;从活动内容来区分又可分为秒杀云服务器和新用户特惠云服务器&#xff0c;下面是截止目前&#xff0c;阿里云服务器最新的秒杀及新用户特惠购买价格&#xff0c;以表格形式形式展示出来以供参考。 阿里…

​ICLR 2023 | 图数据分布外检测:从能量模型出发

©PaperWeekly 原创 作者 | 吴齐天单位 | 上海交通大学博士生研究方向 | 机器学习与图深度学习继续探索 Graph OOD 的相关问题&#xff0c;与以往工作不同的是&#xff0c;这篇工作避开了复杂的数学推导和琐碎的数据生成过程&#xff0c;直接从简单有效的判别模型入手研究…

【Spring】掌握 Spring Validation 数据校验

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Spring Validation 数据校验一、什么是 Spring…

RAN-in-the-Cloud:为 5G RAN 提供云经济性

RAN-in-the-Cloud&#xff1a;为 5G RAN 提供云经济性 5G 部署在全球范围内一直在加速。 许多电信运营商已经推出了5G服务并正在快速扩张。 除了电信运营商之外&#xff0c;企业也对使用 5G 建立私有网络产生了浓厚的兴趣&#xff0c;这些私有网络利用了更高的带宽、更低的延迟…

【编程基础之Python】8、Python复合数据类型

【编程基础之Python】8、Python复合数据类型Python复合数据类型列表&#xff08;List&#xff09;创建列表访问元素内置方法列表操作元组&#xff08;Tuple&#xff09;创建元组访问元素集合&#xff08;Set&#xff09;创建集合基本操作其他操作字典&#xff08;Dictionary&am…

4.ffmpeg命令转码规则、过滤器介绍、手动流map选项

在上章我们学习了ffmpeg命令行帮助以及选项查找 本章我们来深入学习ffmpeg命令转码规则、过滤器介绍、手动流map选项 参考链接: 1.ffmpeg命令行转码流程 ffmpeg命令行转码流程如下图所示: 对应中文则是: 步骤如下所示: ffmpeg调用libavformat库(包含解复用器)来读取输入文件…

Linux -- 查看进程 PS 命令 详解

我们上篇介绍了&#xff0c; Linux 中的进程等概念&#xff0c;那么&#xff0c;在Linux 中如何查看进程呢 &#xff1f;&#xff1f;我们常用到的有两个命令&#xff0c; PS 和 top 两个命令&#xff0c;今天先来介绍下 PS 命令~&#xff01;PS 命令 &#xff1a;作用 &#x…

C语言拔高知识——指针的进阶(万字大文超详细)

在之前的文章中&#xff0c;我已经讲解过了初阶指针的内容&#xff0c;今天就来讲一讲指针的进阶&#xff01; 上篇指针地址&#xff1a;保姆式指针讲解&#xff0c;超详细&#xff0c;适合初学者_指针详解_陈大大陈的博客-CSDN博客 目录 1. 字符指针 2. 指针数组 3. 数组指…

3年测试经验的人来面试,简历都没写明白,一开口就要给20K的offer?

​我最近阅读了大约15份简历&#xff0c;他们都在申请我的团队的测试工程师职位。但是没有一份表达清楚了他是如何进行测试的。 下面我摘录了一些 信息&#xff1a; 几乎所有的应聘者都罗列了成串儿的他们熟悉的“技术”&#xff08;包括但不限于….Net&#xff0c; Unix&#…

c++基础/类和对象

c基础 2.1名字空间 namespace 防止命名冲突 说明&#xff1a;名字空间可以在全局作用域或其他作用域&#xff08;另一个名字空间&#xff09;内部定义&#xff0c;但不能在函数或类的内部定义。 使用&#xff1a; #include<iostream> using namespace std; //std中包…