java数据结构与算法基础-----字符串------正则表达式---持续补充中

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

目前校招的面试,经常会遇到各种各样的有关字符串处理的算法。掌握正则表达式可以秒杀大部分普通方法处理起来偏难的题目。
而且正则表达式也是实际工作中使用频率非常高的工具。

记得几年前学习正则表达式,因为当时英语不好,所以是从b站视频入手学习的,今天回到b站搜了一下,发现依然是韩顺平老师讲解的比较全面。本文也是当年我学习这套视频所做的笔记(只不过当时记在了A4纸上),这么多年如果涉及使用正则表达式的场景,也是直接翻笔记就搞定了。链接如下:

韩顺平JAVA,正则表达式:https://www.bilibili.com/video/BV1Eq4y1E79W/

但是要注意,正则表达式的效率不如直接进行字符操作。所以做题时,使用正则表达式尽量不要对同一个子串进行超过一次以上的匹配。否则反而影响效率。

如何正确使用正则表达式提升效率呢?只要是字符操作十分繁琐麻烦,而使用正则可以一步到位的情况都可以使用。例如下面Leetcode205题,我们想要跳过一些比较有规律,但是处理起来比较繁琐的字符串时,就可以使用正则表达式来处理

  1. 没有使用正则
    在这里插入图片描述
  2. 使用了正则后
    在这里插入图片描述

文章目录

  • 一、正则底层实现概述
    • 1. matcher.find()
    • 2. matcher.group(0)
    • 3. 分组情况下
  • 二、正则表达式语法
    • 1. 正则转义符
    • 2. 字符匹配符
    • 3. 选择匹配符
    • 4. 正则限定符
    • 5. 正则定位符
  • 三、分组
    • 1. 捕获分组
    • 2. 非捕获分组
  • 四、实战案例

一、正则底层实现概述

这里很重要,一定要掌握,否则大家后面学再多语法,都不知道为什么这样用。

拿一段简单的测试代码,来讲解两个重要的方法的底层实现。这里使用的是java语言,其它语言大同小异。
  1. 下面代码的功能是,实现从文本中提取出所有的IP地址
    在这里插入图片描述
package com.yzpnb.pattern;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        String content = "私有地址(Private address)属于非注册地址,专门为组织机构内部使用。\n" +
                "以下列出留用的内部私有地址\n" +
                "A类 10.0.0.0--10.255.255.255\n" +
                "B类 172.16.0.0--172.31.255.255\n" +
                "C类 192.168.0.0--192.168.255.255";
        Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+");//匹配规则,这里实现匹配文本中所有的IP地址
        int no = 0;//无关紧要,下面输出时我想输出一个序号
        Matcher matcher = pattern.matcher(content);//按照pattern定义的匹配规则,到content中匹配
        while(matcher.find()){//matcher.find()如果匹配成功就返回true,否则返回false
            //匹配内容,文本,放到group组中。
            System.out.println("找到:"+(++no)+" "+matcher.group(0));//输出
        }
    }
} 

1. matcher.find()

功能概述
  1. 根据指定规则,定位字符串中满足规则的子字符串
  2. 定位成功后,此方法返回true
  3. 同时会将子字符串的开始索引记录到matcher对象的一个,类型为int型一维数组的属性中(int[] groups)
  4. 假设找到的子字符串起始下标为start,结尾下标为end。那么会让groups[0] = start;groups[1] = end+1
  5. end+1很重要,它可以方便我们下次匹配,减少工作量。所以只要涉及到结尾下标,几乎都保存结尾下标+1的值。比如String.substring(start,end)方法,都是包含start不包含end的区间。
原理解析
  1. matcher实例化后:
  1. 可以看到下图中,matcher对象中会有一个初始大小为20的groups数组,初始值为-1
    在这里插入图片描述
  2. 同时,first变量初始值也是1,last为0,oldLast也是-1
    在这里插入图片描述
  1. 当执行find()方法后:
  1. 我们会发现,它会在groups[0]记录找到的子串的起始下标。groups[1]会记录结尾下标+1。为什么要记录结尾下标+1呢?是因为方便我们下次查找时,直接跳过已经查找过的。
    在这里插入图片描述
  2. 同时,会将本次结尾下标+1这个值,作为下次查找的起始地址保存到oldLast属性中

另外first属性保存本次匹配成功的串的起始位置,last属性保存本次匹配成功的串的结束位置+1.
在这里插入图片描述

2. matcher.group(0)

功能概述
  1. 根据groups[0]=59和groups[1]=67记录的值,从字符串中,截取groups[0]到groups[1]之间的子字符串. 左闭右开区间:[ 59 , 67 ) === 闭区间:[ 59 , 66 ]
为什么我们例子中group()方法中传参为0呢?为什么不group(1)?
  1. 下面是group方法的源码:
  1. 第一个if语句:如果成功使用find()方法匹配,first会>=0,否则抛出没匹配到的异常
  2. 第二个if语句:我们调用group()方法时,这个传参必须>=0. 并且 这个值也必须<=组的个数(groups[]数组的下标范围,不可越界)否则抛出下标越界异常
  3. 第三个if语句,如果获取指定groups[]数组中的值为-1,就返回null
  4. 最后的return,就是为什么传参需要为0
  1. 我们上面的例子中,我们匹配后的子串下标,保存在groups[0]和groups[1]中
  1. 这是因为find()这个方法是可以一次找到多个的。第0个放在groups[0]和groups[1]中。如果有第1个,就放在groups[2]和groups[3]中,依次类推。
  2. 现在group()方法,想要实现我们传0,获取第0个,我们传1获取第1个是如何实现的呢?

每一个都有两个下标,0 * 2 = 0 , 0 * 2+1 = 1. 这样就获取第0个子串的groups[]数组下标
同理,如果我们传参为1,就说明我们想要第1个子串。1 * 2 = 2 , 1 * 2 + 1 = 3. 这样就获取了第1个子串的groups[]数组下标了。

public String group(int group) {
    if (first < 0)
        throw new IllegalStateException("No match found");
    if (group < 0 || group > groupCount())
        throw new IndexOutOfBoundsException("No group " + group);
    if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
        return null;
    return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}

3. 分组情况下

前面的案例,是只考虑分一组的情况,只会使用到groups[0]和groups[1]两个数组元素。下面分析分多组的情况。

下面的案例中,我将ip地址10.0.0.0分组,每组保存IP地址的数字,也就是10,0,0,0去掉那些点,只保留每两个点之间的数字
在这里插入图片描述

package com.yzpnb.pattern;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        String content = "私有地址(Private address)属于非注册地址,专门为组织机构内部使用。\n" +
                "以下列出留用的内部私有地址\n" +
                "A类 10.0.0.0--10.255.255.255\n" +
                "B类 172.16.0.0--172.31.255.255\n" +
                "C类 192.168.0.0--192.168.255.255";
        Pattern pattern = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)");//匹配文本中所有的IP地址
        int no = 0;//无关紧要,下面输出时我想输出一个序号
        Matcher matcher = pattern.matcher(content);//按照pattern定义的匹配规则,到content中匹配
        while(matcher.find()){//matcher.find()如果匹配成功就返回true,否则返回false
            //匹配内容,文本,放到group组中。
//            System.out.println("找到:"+(++no)+" "+matcher.group(0));//输出
            System.out.println("matcher.group(0):"+matcher.group(0));
            System.out.println("matcher.group(1):"+matcher.group(1));
            System.out.println("matcher.group(2):"+matcher.group(2));
            System.out.println("matcher.group(3):"+matcher.group(3));
            System.out.println("matcher.group(4):"+matcher.group(4));
            System.out.println("matcher.group(5):"+matcher.group(5));
        }
    }
}

  1. 可以发现,上面我们分了4组,实际上保存了5组到groups[]数组中
  2. 其中group(0)获取到的第0组,为整个匹配规则匹配到的完整子串
  3. 而剩下的group(1)到group(4)为我们想要的分组,分别为4个点与点之间的数字
  4. 而group(5)是为大家演示,下标越界异常。没有第5组
第0组遵循end+1原则。而其它分组,也同样遵循end+1

在这里插入图片描述

  1. 第0组因为是保留完整匹配成功的子串。依然会遵循前面案例分析的,groups[1]依然保存end+1的位置,方便下次匹配。
  2. 而其它组,它的末尾根本就不是下一次匹配应该开始的位置。但是,完全没必要因为这个就特殊处理其它组,所以也都保存end+1的位置。

二、正则表达式语法

元字符(Metacharacter)分为:限定符、选择匹配符、分组组合和反向引用符、特殊字符、字符匹配符、定位符

1. 正则转义符

转义号:\\,用来指定后面的字符,当做字符,而不当做关键字。

简单来讲,我们以普通转义字符(字符串,不是正则)为例。java中字符串用两个双引号 “字符串” 来标识。那么如果字符串中,包含双引号怎么办呢?例如" 这是一个"字符串"哦! “,此时java就会报错,因为它不知道从哪开始到哪结束算作一个字符串。而需要转义” 这是一个\ "字符串\ "哦! "
在这里插入图片描述
在这里插入图片描述

  1. 正则表达式与普通字符串中的转义原理一样,但是普通字符串用一个反斜杠\表示转义字符,而正则表达式用两个反斜杠\\表示转义字符
  1. 用正则表达式检索某些特殊字符,需要转义符号,否则会无法完成检索,甚至报错(因为这些符合直接出现在正则表达式中,富有特殊的含义。因此只是当做普通字符使用时,必须转义)

常见的需要用转移符号的字符如下:[.,*,+,(,),$,/,\,?,[,],^,{,}]

  1. Java的正则表达式和其它大部分语言不同,其它语言的转义号是\(一个反斜杠),而Java是\\(两个反斜杠)
  2. 下面是例子,尝试匹配$符号
  1. 直接用 $ 来匹配 $ 符号,可以发现结果为空
    在这里插入图片描述
  2. 用 \ \ $来匹配,可以发现匹配成功
    在这里插入图片描述

2. 字符匹配符

在正则表达式中有特殊意义的字符,这些字符往往就是前面讲的需要转义字符\\标识,才能识别为普通字符的字符。直接使用这些字符,将富有特殊的含义。而反过来,普通的字母。例如w如果进行转义\\w,也会富有特殊的含义。这些都是设计者所规定的规则,我们使用时,记住并遵守这些约定即可。

符号描述示例(示例中有不认识的符号,可以参考正则限定符中内容)示例解析
[ ]规定当前位置匹配可选字符列表[abcd]当前位置可选a,b,c,d中任意一个字符
[^ ]规定当前位置匹配,不接收的字符列表[^abcd]当前位置可选,除了a,b,c,d之外的任意一个字符
-连字符A-Z任意从A到Z的单个大写字母
.匹配除 \n(换行符)以外的任何字符a..b以a开头,b结尾,中间两个点表示,这两个位置可以匹配任意字符长度为4的字符串(例如:aaab、a35b、a#*b…)
\\d默认匹配单个数字字符,等价与[0-9],是\\d{1}的简写形式.如果后面加个{}表示匹配几个,例如\\d{3}表示匹配3个数字字符\\d{3}(\\d)?匹配3或4个数字
\\D\\d的相反匹配规则。匹配单个数字字符,等价于[^0-9],同样可以使用{}\\D(\\d)*单个非数字字符开头,后接任意个数字字符(例如:a,A342)
\\w匹配单个数字、大小写字母和下划线_,相当于匹配[0-9a-zA-Z]\\d{3}\\w{4}以3个数字字符开头,后面4个是任意数字,大小写字母组成的,长度为7的数字字母字符串
\\W\\w的相反匹配规则。匹配单个数字、大小写字母和下划线,相当于[^0-9a-zA-Z]\\W+\\d{2}以至少1个非数字字母字符开头,2个数字字符结尾的字符串
(?i)后面的匹配规则进行匹配时,不区分大小写,其中i是字母i,是单词Insensitive (adj.不敏感的;漠不关心的;)的缩写(?i)abc 或 a(?i)bc 或 a((?i)b)c1、abc都不区分大小写 2、bc不区分大小写 3、只有b不区分大小写
\\s匹配任何空白字符(空格,制表符)a\\sb匹配a空格b或者a制表符b等结果
\\S\\s的相反匹配规则,匹配任何非空白字符a\\Sb只要是a和b之间不是一个空白字符,就匹配
待续待续待续待续待续待续待续待续待续待续待续待续待续待续待续续待续待续续待续待续续待续待续续续待续待续待续待续待续待续待续
额外的实现(?i)效果的方法(不区分大小写):其中i是字母i,是单词Insensitive (adj.不敏感的;漠不关心的;)的缩写

正常状况下,我们匹配abc,默认是区分大小写的,也就是无法匹配到ABC

  1. 第一个方法是在正则表达式中使用(?i)
  1. 下图中实现通过(?i),用abc匹配到了ABC的效果
    在这里插入图片描述
  2. 而直接使用abc匹配,则无法匹配到ABC
    在这里插入图片描述
  1. 额外的方法是:生成Pattern对象时,指定参数Pattern.CASE_INSENSITIVE, 实现不区分大小写,但是这种方法只能实现整体不区分大小写,无法和(?i)一样实现精细控制某一个字符不区分大小写的目的
    在这里插入图片描述

3. 选择匹配符

一个竖杠|就是选择匹配符,和或运算符||有异曲同工之妙.表示只要满足一个条件就匹配

例如我们想要实现匹配Java或者抓哇。两个随便一个都行,就可以通过选择匹配符来实现。下面的例子中,想要在字符串java抓哇中,匹配出java或者抓哇。那么就可以使用正则表达式java|抓哇
在这里插入图片描述

4. 正则限定符

java默认贪婪匹配,例如+代表匹配1个或多个,如果当前字符串符合条件的连续字符有多个,默认贪婪匹配多个,而不是1个1个匹配。

如何取消贪婪匹配,选择用非贪婪匹配呢?只需要限定符后面加个?即可。例如我们想要从java0123完成匹配

  1. java\\d*表示java开头,后面跟随0或多个数字。会直接匹配出java0123,因为是贪心匹配,优先尽可能多的匹配
    在这里插入图片描述
  2. java\\d*?表示java开头,后面跟随0或多个数字,并且非贪婪匹配。则会匹配出java,因为是非贪婪匹配,优先尽可能少的匹配,而*表示匹配0或多个,最少就是0个,所以非贪婪优先最少,也就是0个
    在这里插入图片描述
符号描述示例(示例中有不认识的符号,可以参考正则限定符中内容)示例解析
{num}按指定规则一次性匹配num个字符\\d{3}按照\\d规则,匹配连续的3个字符,这3个字符全部满足\\d规则
?按照指定规则,匹配0或1个字符\\d?按照\\d规则,匹配0或1个字符
*按照指定规则,匹配任意个字符(0个,1个或多个)\\d*按照\\d规则匹配任意个
+按照指定规则,匹配1个或多个字符\\W+按照\\W规则,匹配非数字或字母字符,1个或多个
{num}:按照指定规则,连续num个字符匹配。就是至少连续num个符合指定规则的字符才能完成匹配

使用例子"123abc1234abc123456789",我们要对其中123,1234,123456789进行匹配

  1. 直接用{num}形式,表示必须num个,不能多也不能少。下面例子中,我们按照1[0-9]规则并限定[0-9]{2}.也就是1开头,后面跟[0-9]数字,必须长度为2,不能多也不能少。

下图结果中可以看出,1开头满足后,只会匹配2个[0-9]的数字,多一个少一个都没有匹配到
在这里插入图片描述

  1. 用{num,}形式,表示至少匹配num个,上不封顶,我们[0-9]{num,}进行匹配时,会匹配[0-9]至少两个,多了也没关系,但是不能少

下图结果中可以看出,1开头满足后,后面匹配[0-9]至少2个,但是上不封顶
在这里插入图片描述

  1. 用{left,right}形式,至少匹配left个,最多匹配right个。默认贪婪匹配,如果一次性匹配不完(原字符串符合规则字符个数超出right,优先先匹配right个,剩下的再依次匹配)

下图中,我们限定开头必须是1,且对[0-9]限定至少2个,最多4个。匹配结果也同样满足条件
在这里插入图片描述

5. 正则定位符

规定要匹配的字符串出现的位置,比如在字符串开始还是结束位置。换句话说:指定要匹配的位置

符号描述示例(示例中有不认识的符号,可以参考正则限定符中内容)示例解析
^指定起始字符^[0-9]+[a-z]*至少1个数字开头,后接任意个小写字母
$指定结束字符^[0-9]\\-[a-z]+$以一个数字开头,接连字符"-",至少1个小写字母结尾
\\b匹配以指定规则结尾的边界yin\\b*边界:用空格分开的子串的两边,或目标字符串的起始和结束位置,例如这个字符串“yinabcdyin aaaayin”,标黄的位置就是以yin结尾的边界
\\B\\b的含义正好相反,匹配以指定规则开头的边界yin\\Byinabcdyin aaaayin”,其中标黄的是以yin为开头的边界
待续待续待续待续待续待续待续待续待续待续待续待续待续待续待续续待续待续续待续待续续待续待续续续待续待续待续待续待续待续待续

三、分组

适用于,我们匹配到内容后,想要单独获取其中某一部分的场景
例如匹配ip地址,10.0.76.1 我们匹配成功后,想要单独获取第3个字段中的内容76,就可以用分组来实现

1. 捕获分组

  1. (pattern):用一对小括号来实现分组称为非命名捕获。捕获匹配的子字符串。编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其它捕获结果则根据左括号的顺序从1开始自动编号。

pattern是匹配规则,也就是要分组的正则表达式

  1. (? < name>pattern):命名捕获。将匹配的子字符串捕获到一个组名称或编号名称中,用于name的字符串不能包含任何标点符合,并且不能以数字开头。可以使用单引号代替尖括号。例如(?'name’pattern)
命名捕获,实战中基本都是使用命名捕获,只有很简单的匹配会使用非命名捕获

最上面的底层实现中,我们已经介绍过非命名捕获了。接下来是命名捕获,通过使用group方法的重载实现,这个group方法的源码如下,通过字符串获取对应组下标,然后剩下的逻辑和非命名一致。
在这里插入图片描述

  1. 我们想要实现,从一个字符串中,匹配出IP地址,并且通过"one"获取ip第一个字段,"two"获取第二个,"three"和"four"获取第3个和第4个
    在这里插入图片描述
  2. 上图中发现,我们通过(?< name>)的方式为分组命名,并通过group方法,使用指定name获取分组内容。
public static void main(String[] args) {
        String content = "alksdjflksjal====192.168.0.1====kfjlkasjflkjdsladf";
        Pattern pattern = Pattern.compile
                ("(?<one>[0-9]{1,3})." +
                "(?<two>[0-9]{1,3})." +
                "(?<three>[0-9]{1,3})." +
                "(?<four>[0-9]{1,3})");//匹配文本中所有的IP地址
        Matcher matcher = pattern.matcher(content);//按照pattern定义的匹配规则,到content中匹配
        while(matcher.find()){//matcher.find()如果匹配成功就返回true,否则返回false
            System.out.println("matcher.group(0):"+matcher.group(0));
            System.out.println("matcher.group(\"one\"):"+matcher.group("one"));
            System.out.println("matcher.group(\"two\"):"+matcher.group("two"));
            System.out.println("matcher.group(\"three\"):"+matcher.group("three"));
            System.out.println("matcher.group(\"four\"):"+matcher.group("four"));
        }
    }

2. 非捕获分组

想要使用一下分组的功能,但是不想浪费额外空间和时间,放到group(0)之类的。也就是说,捕获分组会将分组的内容捕获并存储。而非捕获分组,只是提供分组功能,但是不进行捕获和存储

常用于"or"字符(|选择匹配符)组合模式部件的情况。
我们知道,分组是独立的,它富有()的功能,也就是括号里的单独处理(数学中,括号里的先算)

  1. (?:pattern):匹配pattern,分组中内容和pattern中匹配即可。简写了选择匹配符的实现,例如我们要匹配java0,java1,java2,java3,…

下面两个表达式等价,它极大的减少了重复操作,实现共有部分写一遍,单独用分组处理不同的部分。

  1. java(?:0|1|2|3)
  2. java0|java1|java2|java3

在这里插入图片描述

    public static void main(String[] args) {
        String content = "java0,java1,java2,java3,java4";
        Pattern pattern = Pattern.compile
                ("java(?:0|1|2|3)");//匹配文本中所有的IP地址
        Matcher matcher = pattern.matcher(content);//按照pattern定义的匹配规则,到content中匹配
        while(matcher.find()){//matcher.find()如果匹配成功就返回true,否则返回false
            System.out.println("matcher.group(0):"+matcher.group(0));
        }
    }
  1. (?=pattern):条件判断pattern,也就是这是将这个分组当做一个匹配条件,不参与到匹配结果中

例如我们想要匹配这个字符串java0,java1,group0,group1,apple0,apple1中,所有后面数字是0的英文字母,并且这个数字0不放入最终匹配结果中

  1. 直接用普通正则[a-z]{4,10}0匹配,无法实现这个效果,可见下面的正则会将数字0也匹配出来
    在这里插入图片描述
  2. 用非捕获分组,[a-z]{4,10}(?=0),可以轻松匹配出这些单词,并且不带后面的0
    在这里插入图片描述
    public static void main(String[] args) {
        String content = "java0,java1,group0,group1,apple0,apple1";
        Pattern pattern = Pattern.compile
                ("[a-z]{4,10}(?=0)");//匹配文本中所有的IP地址
        Matcher matcher = pattern.matcher(content);//按照pattern定义的匹配规则,到content中匹配
        while(matcher.find()){//matcher.find()如果匹配成功就返回true,否则返回false
            System.out.println("matcher.group(0):"+matcher.group(0));
        }
    }
  1. 有啥用?
  1. 当我们想要统计所有1999年生产的手机型号时。例如这个字符串"诺基亚1999,iPhone2018,摩托罗拉1999…",我们想匹配出1999年的所有手机,诺基亚和摩托罗拉。就可以用这个。而不是匹配出诺基亚1999,摩托罗拉1999,最后还得通过其它处理,将1999去掉。
  1. (?!pattern),和(?=pattern)是相反的操作,表示拒绝匹配pattern

我们想要对java0,total1,group0,hotel1,apple0,banana1进行指定匹配

  1. 先用(?=pattern)举例:匹配所有单词,以数字结尾,并且这个数字必须是0. 这个就可以使用(?=pattern)操作,可以使用正则[a-z]{4,}(?=\d)(?=0),表示最少4个字母,并且以数字结尾,并且末尾数字必须为0
    在这里插入图片描述
  2. 匹配所有单词,以数字结尾,但是这个数字不能为0.这时就用(?!pattern)操作,可以使用正则[a-z]{4,}(?=\d)(?!0)实现最少4个字母,以数字结尾,并且末尾数字必须不能为0
    在这里插入图片描述

四、实战案例

因为篇幅原因,我将其放在另一篇文章中:https://blog.csdn.net/grd_java/article/details/136963602

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【docker系列】深入理解 Docker 容器管理与清理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

JVM——运行时数据区

前言 由于JAVA程序是交由JVM执行的&#xff0c;所以我们所说的JAVA内存区域划分也是指的JVM内存区域划分&#xff0c;JAVA程序具体执行的过程如下图所示。首先Java源代码文件会被Java编译器编译为字节码文件&#xff0c;然后由JVM中的类加载器加载各个类的字节码文件&#xff0…

解决win10安装软件提示Microsoft Store界面

解决方法 1. 打开设置&#xff0c;找到应用 2. 应用与功能&#xff0c;选择任何来源

Day18:LeedCode 513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树

513. 找树左下角的值 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1 思路:出该二叉树的 最底层 最左边 节点的值找出深度最大的第一个结点(左结点先遍历) 方法一…

【数据挖掘】实验5:数据预处理(1)

实验5&#xff1a;数据预处理&#xff08;1&#xff09; 一&#xff1a;实验目的与要求 1&#xff1a;熟悉和掌握数据预处理&#xff0c;学习数据清洗、数据集成、数据变换、数据规约、R语言中主要数据预处理函数。 二&#xff1a;实验内容 【缺失值分析】 第一步&#xff1…

java selenium 元素点击不了

最近做了一个页面爬取&#xff0c;很有意思被机缘巧合下解决了。 这个元素很奇怪&#xff0c;用xpath可以定位元素&#xff0c;但是就是click()不了。 试过了网上搜的一些办法&#xff1a; //尝试一 WebElement a_tag driver.findElement(By.xpath("xxx")); a_tag…

【SysBench】OLTP 基准测试示例

前言 本文采用 MySQL 沙盒实例作为测试目标&#xff0c;使用 sysbench-1.20 对其做 OLTP 基准测试。 有关 MySQL 沙盒的更多信息&#xff0c;请参阅 玩转 MySQL Shell 沙盒实例&#xff0c;【MySQL Shell】6.8 AdminAPI MySQL 沙盒 。 1、部署一个 MySQL 沙盒实例 使用 mysq…

云计算 3月18号 (mysql安装及操作)

一、Mysql 1.1 MySQL数据库介绍 1.1.1 什么是数据库DB&#xff1f; DB的全称是database&#xff0c;即数据库的意思。数据库实际上就是一个文件集合&#xff0c;是一个存储数据的仓库&#xff0c;数据库是按照特定的格式把数据存储起来&#xff0c;用户可以对存储的数据进行…

mac 安装 nvm 【真解决问题】

前提 没有node环境已有git 下载 我用的gitee极速下载 git clone https://gitee.com/mirrors/nvm.git ~/.nvm && cd ~/.nvm && git checkout git describe --abbrev0 --tags配置 1. 配置变量 在用户的目录下新增文件 .zshrc export NVM_DIR"$HOME/…

[数据结构]二叉树(下)

一、二叉树的节点和深度关系 1.满二叉树 我们可以假设二叉树有N个节点&#xff0c;深度为h我们可以恒容易得到满二叉树每行的节点数&#xff0c;然后错位相减,算出节点与高度的关系。 2.完全二叉树 注意我这个是因为最后一行的节点数为1。 二、向上调整建堆和向下调整建堆的时…

【Node.js】CSR、SSR、SEO

SSR 和 CSR SSR &#xff08;Server-Side Rendering&#xff09;服务端渲染&#xff0c;请求数据和拼装都在服务端完成&#xff0c;相当于在服务端直接完成html。 而 Vue,react 等框架&#xff0c;是在客户端完成渲染拼接的&#xff0c;属于CSR&#xff08;Client-Side Rende…

Linux/openEuler系统部署spring boot+vue前后端分离项目(nginx均衡代理)

Linux/openEuler系统部署spring bootvue前后端分离项目&#xff08;nginx均衡代理&#xff09; 1、系统环境准备&#xff0c;安装openjdk和nginx还有MySQL&#xff0c;咱们本文先连接主机mysql进行登录&#xff08;linux上的mysql服务可以先不安装&#xff09; 可以看我前面的…

【神经网络】得分函数,损失函数~

目录 引言 一、神经网络概述 1 定义 2 基本原理 二、得分函数 1 定义 2 应用方法 3 与神经网络 三、损失函数 1 定义 2实现方法 3 与神经网络 四、得分函数与损失函数的协同作用 1 关系 2 实际应用 六、代码事例 &#xfffc;、总结与展望 引言 在人工智能与机…

40 openlayers setCenter 之后 绘制了Overlay 地图定位异常

前言 这是之前在 生产环境碰到的一个问题 这个其实就是 业务上一个地图点击点位展示详情, 然后再点击另外一个点位 展示详情, 切换中心店的这个过程 其主要的问题是 使用 openlayers 的 Map.View.setCenter() 了之后, 整个地图的中心点切换到了一个莫名其妙的地方 然后 经…

Linux的学习之路:2、基础指令(1)

一、ls指令 上篇文章已经说了一点点的ls指令&#xff0c;不过那还是不够的&#xff0c;这篇文章会介绍更多的指令&#xff0c;最起码能使用命令行进行一些简单的操作&#xff0c;下面开始介绍了 ls常用选项 -a 列出目录下的所有文件&#xff0c;包括以 . 开头的隐含文件。 -d…

3.4网安学习第三阶段第四周回顾(个人学习记录使用)

本周重点 ①CSRF跨站请求伪造 ②跨域访问 ③文件包含 ④文件上传 ⑤文件下载漏洞 ⑥XXE外部实体注入 本周主要内容 ①CSRF跨站请求伪造 一、概述&#xff1a; csrf: cross site request forgrey 跨站请求伪造。当攻击者不能通过常用的手段获取cookie时候&#xff0c;…

SQL Server 2008R2 日志文件大小设置及查询

SQL Server 2008R2 建立数据库存在日志无限增长问题&#xff0c;造成磁盘内存不足。本文解决这个问题&#xff0c;如下&#xff1a; 1.设置日志文件的最大大小 USE master; GO ALTER DATABASE [D_total] MODIFY FILE (NAME D_total_log, -- 日志文件的逻辑名称MAXSIZE 200…

信号处理--基于FBCSP滤波方法的运动想象分类

目录 理论 工具 方法 代码获取 理论 通用空间模式 (CSP) 算法可以用来有效构建最佳空间滤波器区分&#xff0c;然后实现运动想象的数据中的脑电信号的区分。然而&#xff0c;空间滤波器性能的好坏主要取决于其工作频带。如果脑电信号没有经过滤波或者滤波的频带范围不合适…

计算机组成原理 微程序控制器组成实验

一、实验目的 1.掌握时序产生器的组成原理。 2.掌握微程序控制器的组成原理。 3.掌握微指令格式的化简和归并。 二、实验任务 1、按实验要求连接实验台的数码开关K0-K5、按钮开关、时钟信号源和微程序控制器。注意&#xff1a;本次试验只做微程序控制器本身的实验&#xf…

安科瑞ANET智能物联网网关 通信管理机-安科瑞 蒋静

概述 本系列智能通信管理机是一款采用嵌入式硬件计算机平台&#xff0c;具有多个下行通信接口及一个或者多个上行网络接口&#xff0c;用于将一个目标区域内所有的智能监控/ 保护装置的通信数据整理汇总后&#xff0c;实时上传主站系统&#xff0c;完成遥信、遥测等能源数据采集…