字符串的匹配算法【学习算法】

news2024/11/27 22:37:12

字符串的匹配算法【学习算法】

  • 前言
  • 版权
  • 推荐
  • 字符串的模式匹配
    • BF模式匹配算法
    • KMP模式匹配算法
  • Java中实现算法
    • 官方题解
    • 调用Java的API
    • 参考Java的API
    • BF算法
    • KMP算法
  • C中实现算法
    • KMP算法
  • 最后

前言

2023-8-6 12:06:42

以下内容源自《【学习算法】》
仅供学习交流使用

版权

禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
博客主页是https://blog.csdn.net/qq_51625007
禁止其他平台发布时删除以上此话

推荐

28. 找出字符串中第一个匹配项的下标

字符串的模式匹配


知识内容来源于
第四章 串(数据结构与算法)


子串的定位操作是找子串在主串中从第 pos 个字符后首次出现的位置,又被称为“串的模式匹配"或“串匹配”,此运算的应用非常广泛。例如,在文本编辑程序中,经常要查找某一特定单词在文本中出现的位置。显然,解决此问题的有效算法能极大地提高文本编辑程序的响应性能在串匹配中,一般将主串S称为“目标串”,子串T称为“模式串”。

模式匹配的算法很多。本章仅讨论 BF模式匹配和KMP模式匹配这两种串匹配算法。

BF模式匹配算法

[BE算法思想]
Brute-Force 算法又称“蛮力匹配”算法(简称BP算法),从主串S的第pos个字符开始,和模式串了的第一个字符进行比较,若相等,则继续逐个比后续字符;否则回溯到主串的第 pos+1个字符开始再重新和模式串T进比较。以此类推,直至模式串了中的每一个字符依次和主串中的一个连的字符序列全部相等,则称模式匹配成功,此时返回模式串了的第一个字在主串S中的位置;否则主串中没有和模式串相等的字符序列,称模式匹配不成功。

[BF算法描述]
从主串S的第pos个字符开始的子串与模式串T比较的策略是从前到后依次进行比较。因此在主串中设置指示器i表示主串S中当前比较的字符;在模式串T中设置指示器j表示模式串T中当前比较的字符。

如图4-5所示,给出了一个匹配过程的例子,其中方框阴影对应的字符为主串S和模式串T比较时不相等的失配字符(假设 pos=1)。

从主串S中第pos个字符起和模式串T的第一个字符比较,若相等则继续逐个比较后续字符,此时i++;j++;否则从主串的下一个字符(i-j+2)和模式串的第一个字符(j=1)比较,分析详图4-6(a)。

当匹配成功时,返回模式串T中第一个字符相对于在主串的位置(i-T.en);否则返回0,分析详见图4-6(b),其中m是模式串的长度T.len。

int Index(SString S,int pos,SString T)
	int i=pos,j=1;//主串从第pos开始,模式串从头开始
	while (i<=S.len&&j<=T.len){
		if(S.ch[i]==T.ch[j]){//当对应字符相等时,比较后续字符
			i++;
			j++;
		}
		else{				//当对应字符不等时
			i=i-j+2;			//主串回溯到j-j+2的位置重新比较
			j=1;				//模式串从头开始重新比较
		}
	if(j>T.len)	return i-T.len;	//匹配成功时,返回匹配起始位置
	else return 0;				//匹配失败时,返回0

[BF算法分析]
BF算法的思想比较简单,但当在最坏情况下时,算法的时间复杂度为0(n×m),其中n和m分别是主串和模式的长度。这个算法的主要时间耗费在失配后的比较位置有回溯,因而造成了比较次数过多。为降低时间复杂度可采用无回溯的算法。

KMP模式匹配算法

[KMP算法思想]
Knuth-Morris-Pratt算法(简称KMP),是由DEKnuthJ.HMorris和V.RPratt 共同提出的一个改进算法。KMP算法是模式匹配中的经典算法,和BF算法相比,KMP算法的不同点是消除了 BF算法中主串S指针i回溯的情况。改进后算法的时间复杂度为0(n+m)。

[KMP算法描述]
KMP算法中,每当一趟匹配过程中出现字符比较不等时,主串S中的指针不需回溯,而是利用已经得到的“部分匹配”结果将模式串向右“滑动”尽可能远的一段距离后,继续进行比较。

回顾图4-5的匹配过程示例,在第三趟匹配中,当i=7、j=5字符比较不等时,又从i=4.j=1重新开始比较。然而,经过仔细观察可发现,在i=4和j=1,i=5和j=1以及i=6和j=1这三次比较都是不必进行的。因为从第三趟部分匹配的结果就可得出,主串中第4、5、6个字符必然和模式串中的第2.3.4个字符相等,即都是’bca。因为模式串中的第一个字符是’a’,因此它无须再和这三个字符进行比较,而仅需将模式串向右滑动三个字符的位置继续进行i=7.j=2时的字符比较即可。同理,在第一趟的匹配中出现字符不等时,仅需将模式向右移动两个字符的位置进行i=3、j=1时的字符比较。因此,在整个匹配的过程中,指针没有回溯,如图4-7所示。

在这里插入图片描述

一般情况下,假设主串为’S1S2…Sn’,模式串为’T1T2…Tn’,从上例的分析可知,为了实现KMP算法,需要解决以下问题,当匹配过程中产生“失配”(即Si≠Ti)时,模式串“向右滑动”可滑动的距离有名远,也就是说,当主串中字符Si,与模式串中字符Tj"失配”时,主串中字符Si( i 指针不回溯)应与模式串中哪个字符再进行比较?

假设此时主串中字符Si应与模式中字符Tk(k<j)继续进行比较,则主串S和模式串T满 如下关系。
S=S1S2…Si-j+1Si-j+2…Si-k+1…Si-1Si …Sn
T=            T1    T2    …Tj-k+1…Tj-k+2
T=                               T1     …Tk-1

可以看出,若模式串中存在’T1T2…Tk-1’=‘Tj-k+1Tj-k+2…Tj-1’,且满足1<k<j,则当匹配过程中Si≠Tj 时,仅需将模式串向右滑动至第k个字符和主串中第i个字符对齐,匹配仅需从Si、Tk的比较起继续进行,无需i指针的回溯。在匹配过程中为了尽可能“滑动”远一段的距离,因而应选择满足条件较大的k值。

若令next[j]=k,则next[]表明当模式中第j个字符与主串中相应字符“失配”时,在模式中需重新和主串中该字符进行比较的字符的位置。由此可引出模式串的next函数的定义:
请添加图片描述

由此可见next函数的计算仅和模式串本身有关,而和主串无关。其中’T1T2…Tk-1’是’T1T2…Tj-1‘’ 的真前缀子串,'Tj-k+1Tj-k+2…Tj-1’是’T1T2…Tj-1’的真后缀子串。当next函数定义中的集合不为空时 next[j]的值等于串’T1T2…Tj-1’的真前缀子串和真后缀子串相等时的最大子串长度+1

通过以上分析,推导出模式串’abaabcac’的next值的计算过程如表4.1所示。
(1)当j=1时,由定义得知,next[1]=0;
(2)当j=2时,满足1<k<j的k值不存在,由定义得知next[2]=1

请添加图片描述

模式串’abaabcac’的next函数值如图4-8所示。

在求得模式串的next函数之后,匹配可如下进行:假设以指针ij分别指示主串S和模式串T中当前比较的字符,令i的初始值为pos,j的初始值为1。若在匹配过程中Si=Ti,,则ij分别增1;否则,i不变,而j退到 next[j]的位置再比较(即Si和Tnext[j]进行比较),若相等,则指针各自增1,否则j再退到下一个next值的位置,以此类推,直至下列两种可能:一种是j退到某个next值(next[next[···next[j]]])时字符比较相等,则指针各自增1继续进行匹配;另一种是j退到next值为0(即与模式的第一个字符“失配”),则此时需将主串和模式串都同时向右滑动一个位置(此时j=0,当向右滑动一个位置时,即模式串的第一个字符),即从主串的下一个字符Si+1和模式Ti重新开始比较。图4-9是KMP匹配过程的一个例子(假设pos=1)

[算法4-13]KMP模式匹配算法

int Index_KMP( SString S, in pos, SString T){
	int i=pos,i=1;						//主串从第pos开始,模式事从头开始
	while(i<=S.len && j<=Tlen){
		if(j==0||S.ch[j]==T.ch[j]){		//继续比较后续宇符
			++i;++j;
		}else{
			j=next[j];					//模式申向右滑动
		}

if(j>T.len) return i-Tlen;				//匹配成功时,返回匹配的起始位置
else relurn 0							//匹配失败时,返回0

[next算法描述]
KMP算法是在已知模式next函数值的基础上执行的,那么,如何求得模式串的next函数值呢?

由定义可知next[1]=0,假设next[j]=k,这表明在模式串中存在’T1T2···Tk-1’='Tj-k+1Tj-k+2···Tj,这样的关系,其中k为满足1<k<j的某个值此时next[j+1]的值可能有以下两种情况。

(1)若Tj=Tk则表明在模式串中T1T2···Tk-1’='Tj-k+1Tj-k+2···Tj

(2)若T=T则表明在模式串中 TTTTT-T
此时可将求next函数值的问题看成是一个模式匹配的问题,整个模式串既是主串又是模式串其中1<k’<k<j。

①T=Tp-TTTTTT=Te1T-TT=TTT-nei[时若T=Tp,且k=next[h],则next[j+1]=k’+I,即next[j+1]=next[k]+1,也相当于next[j+1]=nextnext[jl]+la
②若T≠Te则继续比较T和T即比较T和T

然后一直重复下去,若直到最后j=0时都未比较成功,则next[j+I]=l。通过以上分析,计算第j+1个字符的 next 值时,需看第个字符是否和第j个字符的next值指向的字符相等。

由此推导出模式串T=abaabcac的next值计算过程如下。
①当j=1时,由定义得知,next[1]=0。
②当j=2时,满足1<h<j的值不存在,由定义得知 next[2]=1。
③当j=3时,由于T2≠T1,且next[1]=0,则nex[3]=1。
④当j=4时,由于T3=T1则next[4]=next[3]+1,即next[4]=2。
⑤当j=5时,由于T4≠T2,且next[2]的值是1,故继续比较T4和T1,由于T4=T1,则next[5]=next[2]+1,即next[5]=2。
⑥当j=6时,由于T5=T2,则next[6]=next[5]+1,即next[6]=3。
⑦当j=7时,由于T6≠T3,且next[3]的值是1,故继续比较T6和T1,由于T6≠T1,且 next[1]=0,则next[7]=1。
⑧当j=8时由于T7=T1,则next[8]=next[7]+1,即next[8]=2。
故得出该模式串的next值如图4-8所示。

[算法4-14]next算法

void Get_Next( SString T, int next[]){
	int j=1,k=0;
	next[1]=0;
	while(j<T.len){
		if(k==0||T.ch[j]==Tch[k] ){
			++j;
			++k;
			nexi[j]=k;
		}else{
			k=next[k];
		}
	}
}

[nextval算法描述]

上述定义的next函数在某些情况下尚有缺陷。假设主串为’aaabaaaab’模式串为’aaaab’,则模式串对应的next函数值如下所示。

在求得模式串的next值之后,匹配过程如图4-10(a)所示。

从串匹配的过程可以看到,当i=4,j=4时,S4不等于T4,由next[j]所示还需进行i=4、j=3;i=4、j=2;i=4、j=1这三次比较。实际上,因为模式申中的第1,2,3个字符和第4个字符都相等(即都是a)因此,不需要再和主串中第4个字符相比较,而可以将模式一次向右滑动4个字符的位置直接进行i=5、j=1的字符比较。

这就是说,若按上述定义得到next[j]=k,而模式串中Tj=Tk,则当Si≠Tj时,不需要进行Si和Tk的比较,直接和Tnext[k]进行比较;换句话说,此时的next[j]的值应和next[k]相同,为此将next[j]修正为nextval[j]。而模式串中Tj≠Tk则当Si≠Tj时,还是需要进行Si和Tk的比较,因此nextval[j]的值就是k,即nextval[j]的值就是next[j]的值。

通过以上分析,计算第j个字符的 nextval值时,要看第j个字符是否和第j个字符的next指向的字符相等。若相等,则nextval[j]=nextval[next[j]];否则,nextval[j]=next[j]。由此推出模式串T='aaaab’的nextval值计算过程如下。

①当j=1时,由定义得知,nextval[1]=0。
②当j=2时,由nex[2]=1,且 T2=T1,则nextval[2]=nextval[1],即nextval[2]=0
③当j=3时,由next[3]=2,且T3=T2,则nextval[3]=nextval[2],即nextval[3]=0。
④当j=4时,由next[4]=3,且T4=T3则nextval[4]=nextval[3],即nextval[4]=0。
⑤当j=5时,由next[5]=4,且T5≠T4,则nextval[5]=next[5],即nextval[5]=4。

模式串’aaaab’的nextal函数值如下所示。

在求得模式串的nextval值之后,匹配过程如图4-10(b)所示。

求nextval函数值有两种方法,一种是不依赖next数组值,直接用观察法求得;另一种方法是如上所述的根据next数组值进行推理,在这里仅介绍第二种方法。

[算法4-15] nextval算法

void Get_NextVal(SString T, int next[ ] ,int nextval[ ]){
	int j=2,k=0;
	Get_Next(T,next);//通过算法4-14获得T的next值
	nextval[1]=0;	
	while (j<=T.len )
		k=next[j];
		if(T.ch[j]==T.ch[k]) nextval[j]=nextyal[ k];
		else nextval[j]=next[j];
		j++;
	}

[KMP算法分析]

KMP算法是在已知模式的 next或nextval的基础上执行的,如果不知道它们两者之一,则没有办法使用KMP算法。虽然有next和 nextval之分,但它们表示的意义和作用完全一样,因此在已知next或nextval进行匹配时,匹配算法不变。

通常模式串的长度m比主串的长度n要小很多且计算next或nextval函数的时间复杂度为0(m)。因此,对于整个匹配算法来说,所增加的计算next或nextval是值得的。

BF算法的时间复杂度为0(nxm),但是实际执行中m往往是远远小于n的,故近似于0(n+m),因此至今仍被采用。KMP算法仅当模式串与主串之间存在许多“部分匹配”的情况下,才会比 BF算法快。KMP算法的最大特点是主串的指针不需要回溯,整个匹配过程中,主串仅需从头到尾扫描一次,对于处理从外设输入的庞大文件很有效,可以边读边匹配。

Java中实现算法

官方题解

class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length(), m = needle.length();
        if (m == 0) {
            return 0;
        }
        int[] pi = new int[m];
        for (int i = 1, j = 0; i < m; i++) {
            while (j > 0 && needle.charAt(i) != needle.charAt(j)) {
                j = pi[j - 1];
            }
            if (needle.charAt(i) == needle.charAt(j)) {
                j++;
            }
            pi[i] = j;
        }
        for (int i = 0, j = 0; i < n; i++) {
            while (j > 0 && haystack.charAt(i) != needle.charAt(j)) {
                j = pi[j - 1];
            }
            if (haystack.charAt(i) == needle.charAt(j)) {
                j++;
            }
            if (j == m) {
                return i - m + 1;
            }
        }
        return -1;
    }
}


调用Java的API

class Solution {
    public int strStr(String haystack, String needle) {
       return haystack.indexOf(needle);
    }
}

参考Java的API

就是利用了BF算法

class Solution {
    public static int strStr(String haystack, String needle) {
        char[] haystackValue=haystack.toCharArray();
        char[] needleValue=needle.toCharArray();
        return index(haystackValue,needleValue);
    }

    public static int index(char[] source, char[] target) {
        int sourceOffset=0;
        int targetOffset=0;
        int sourceCount=source.length;
        int targetCount=target.length;
        int max=sourceOffset+(sourceCount-targetCount);

        char first=target[targetOffset];

        for(int i=sourceOffset;i<=max;i++){
            //找第一个字符
            if (source[i] != first) {
                while (++i <= max && source[i] != first);
            }
            //匹配剩余的部分
            if(i<=max){
                int j=i+1;
                int end=j+targetCount-1;
                for (int k = targetOffset+1; j < end&&source[j]==target[k]; j++,k++);

                if(j==end){
                    return i-sourceOffset;
                }
            }
        }

        return -1;
    }
}

BF算法

class Solution {
    public int strStr(String haystack, String needle) {
        return indexWithBF(haystack,0,needle);
    }

    public static int indexWithBF(String s,int pos,String t){
        int i=pos,j=0;//主串从pos开始,模式串从头开始
        while(i<s.length()&&j<t.length()){
            if(s.charAt(i)==t.charAt(j)){//当对应字符相等时,比较后续字符
                i++;
                j++;
            }else{                      //对应字符不等时
                i=i-j+1;                //主串回溯到i-j+1的位置重写比较
                j=0;                    //模式串从头开始重写比较
            }
        }
        if(j>=t.length()) return i-t.length();  //匹配成功时,返回匹配起始位置
        else return -1;                         //匹配失败时,返回-1
    }
}

KMP算法

class Solution {
    public int strStr(String haystack, String needle) {
        return indexWithKMP(haystack,0,needle);
    }

    public static int indexWithKMP(String s,int pos,String t){
        int[] next=next(t);

        int i=pos,j=0;                      //主串从pos开始,模式串从头开始
        while(i<s.length()&&j<t.length()){
            if(j==-1||s.charAt(i)==t.charAt(j)){//继续比较后续字符
                i++;
                j++;
            }else{                      //模式串向右滑动
                j=next[j];
            }
        }
        if(j>=t.length()) return i-t.length();  //匹配成功时,返回匹配起始位置
        else return -1;                         //匹配失败时,返回-1
    }

    public static int[] next(String t){
        int len=t.length();
        int[] next=new int[len+1];
        int j=0,k=-1;
        next[0]=-1;
        while (j<len){
            if(k==-1||t.charAt(j)==t.charAt(k)){
                j++;
                k++;
                next[j]=k;
            }else{
                k=next[k];
            }
        }
        return next;
    }
}

C中实现算法

KMP算法

int strStr(char* haystack, char* needle) {
    int n = strlen(haystack), m = strlen(needle);
    if (m == 0) {
        return 0;
    }
    int pi[m];
    pi[0] = 0;
    for (int i = 1, j = 0; i < m; i++) {
        while (j > 0 && needle[i] != needle[j]) {
            j = pi[j - 1];
        }
        if (needle[i] == needle[j]) {
            j++;
        }
        pi[i] = j;
    }
    for (int i = 0, j = 0; i < n; i++) {
        while (j > 0 && haystack[i] != needle[j]) {
            j = pi[j - 1];
        }
        if (haystack[i] == needle[j]) {
            j++;
        }
        if (j == m) {
            return i - m + 1;
        }
    }
    return -1;
}

最后

我们都有光明的未来

祝大家考研上岸
祝大家工作顺利
祝大家得偿所愿
祝大家如愿以偿
点赞收藏关注哦

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

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

相关文章

UDS服务基础篇之31

UDS服务基础篇之31服务 前言 正如前文《UDS基础之2F服务》所说的2F服务与今天本文要将的31服务存在着有些相似之处&#xff0c;因此需要针对31服务本身进行较为细致的剖析&#xff0c;在此小T抛出如下几个基本问题供大家思考&#xff1a; 你知道31服务是干什么的吗&#xff…

K8S系列文章之 内外网如何互相访问

K8S中网络这块主要考虑 如何访问外部网络以及外部如何访问内部网络 访问外网服务的两种方式 需求 k8s集群内的pod需要访问mysql&#xff0c;由于mysql的性质&#xff0c;不适合部署在k8s集群内,故k8s集群内的应用需要链接mysql时&#xff0c;需要配置链接外网的mysql,本次测试…

35岁焦虑:体能下滑,新陈代谢变慢,还是我们的日常行为?

35岁焦虑&#xff1a;体能下滑&#xff0c;新陈代谢变慢&#xff0c;还是我们的日常行为&#xff1f; &#x1f607;博主简介&#xff1a;我是一名正在攻读研究生学位的人工智能专业学生&#xff0c;我可以为计算机、人工智能相关本科生和研究生提供排忧解惑的服务。如果您有任…

python的下载和安装步骤,python下载安装教程3.10.0

大家好&#xff0c;给大家分享一下python下载安装教程3.10.0&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 第一步&#xff1a;下载Python安装包 在Python的官网 www.python.org 中找到最新版本的Python安装包&#xff0c;点击进行下载&a…

了解HTTP代理日志:解读请求流量和响应信息

嗨&#xff0c;爬虫程序员们&#xff01;你们是否在了解爬虫发送的请求流量和接收的响应信息上有过困扰&#xff1f;今天&#xff0c;我们一起来了解一下。 首先&#xff0c;我们需要理解HTTP代理日志的基本结构和内容。HTTP代理日志是对爬虫发送的请求和接收的响应进行记录的文…

坐标转换-使用geotools读取和转换地理空间表的坐标系(sqlserver、postgresql)

前言&#xff1a; 业务上通过GIS软件将空间数据导入到数据库时&#xff0c;因为不同的数据来源和软件设置&#xff0c;可能导入到数据库的空间表坐标系是各种各样的。 如果要把数据库空间表发布到geoserver并且统一坐标系&#xff0c;只是在geoserver单纯的设置坐标系只是改了…

听别人说学习机器人哪个方向合适不重要-自己想做什么最重要

2023年7-8月暑期档有一部火热的电影《封神之朝歌风云》 姬昌那句「你是谁的儿子不重要&#xff0c;你是谁才重要」 年轻人要勇于突破权威强加于自身的桎楛&#xff0c;要独立思考&#xff0c;果敢刚毅。 唯有如此才能摆脱工具人的宿命。 AI&#xff1a; 电影《封神之朝歌风云…

IDEA项目实践——Spring框架简介,以及IOC注解

系列文章目录 IDEA创建项目的操作步骤以及在虚拟机里面创建Scala的项目简单介绍 IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介 IDEWA项目实践——mybatis的一些基本原理以及案例 IDEA项目实践——动态SQL、关系映射、注解开发 文章目…

前端js--旋转幻灯片

效果图 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><link rel"stylesheet" href"…

python打印oracle19c版本号

Author: liukai 2810248865qq.com Date: 2022-08-18 04:28:52 LastEditors: tkhywang 2810248865qq.com LastEditTime: 2023-07-08 08:58:24 FilePath: \PythonProject01\&#xfffd;&#xfffd;ӡoracle&#xfffd;&#xfffd;&#xfffd;ݿ&#xfffd;汾&#xfffd;&a…

《孙子兵法》是世界上最著名的中国著作,不服来看,趣讲《孙子兵法》第1讲

《孙子兵法》是世界上最著名的中国著作&#xff0c;不服来看&#xff01;趣讲《孙子兵法》【第1讲】 世界上最有名的中国著作肯定是《孙子兵法》。在著名的美国西点军校是必修课。 在企业管理领域&#xff0c;听一些讲座&#xff0c;经常会引用到《孙子兵法》的一些名句&#…

手把手教你用idea实现Java连接MySQL数据库

目录 1.下载MySQL 2.下载mysql 的jdbc驱动 3.将驱动jar包导入idea 4.通过Java测试数据库是否连接成功 1.下载MySQL 首先如果没有mysql的需要先下载MySQL&#xff0c;可以看这个教程 MYSQL安装手把手&#xff08;亲测好用&#xff09;_程序小象的博客-CSDN博客 2.下载mysql…

IDEA Run SpringBoot程序步骤原理

这个文章不是高深的原理文章&#xff0c;仅仅是接手一个外部提供的阉割版代码遇到过的一个坑&#xff0c;后来解决了&#xff0c;记录一下。 1、IDEA Run 一个SpringBoot一直失败&#xff0c;提示找不到类&#xff0c;但是maven install成功&#xff0c;并且java -jar能成功ru…

红帽8.2版本CSA题库:第三题调试 SELinux

semanage port -a -t http_port_t -p tcp 82 semanage fcontext -m -t httpd_sys_content_t /var/www/html/file1 //必须先做这步再做restorecon restorecon -Rv /var/www/html firewall-cmd --permanent --add-port82/tcp firewall-cmd --reload systemctl enable --now htt…

Fiddler无法抓包怎么解决?这些配置项你需要检查。尤其是最后一项。

有时候&#xff0c;我们的fiddler启动是正常的&#xff0c;但是就是抓不到包&#xff0c;原因有很多。但多数情况都是因为配置不正确&#xff0c;接下来我们就看下有哪些导致fiddler抓不到的设置 。 1 是否配置代理服务器 一般情况下此设置会自动配置&#xff0c;但是如果抓不…

C++拷贝wstring到wchar_t*中踩的坑

使用wchar_t指针将wstring中的数据拿出来&#xff0c;发现释放的时候异常&#xff0c;不是深拷贝和浅拷贝的问题 首先先看看string怎末复制到char中&#xff0c;代码如下 string str1"\"0.2.0\"";char* tnew char[str.size()1];memcpy(t, str1.c_str(), s…

BigDecimal 金额判断大于0、等于0、小于0 方法

方法的使用: BigDecimal.compareTo(BigDecimal.ZERO) public static void main(String[] args) {BigDecimal b1 new BigDecimal(0.01);System.out.println(b1.compareTo(BigDecimal.ZERO)); // 输出 1BigDecimal b2 new BigDecimal(0.00);System.out.println(b2.compareTo(B…

《golang设计模式》第一部分·创建型模式-04-工厂方法模式(Factory Method)

文章目录 1 概述2.1 角色2.2 类图 2 代码示例2. 1 设计2.2 代码2.3 类图 3. 简单工厂3.1 角色3.2 类图3.3 代码示例3.3.1 设计3.3.2 代码3.3.3 类图 1 概述 工厂方法类定义产品对象创建接口&#xff0c;但由子类实现具体产品对象的创建。 2.1 角色 Product&#xff08;抽象产…

Java wait() notify() join()用法讲解

一、wait() 1. 源码&#xff1a; 实际调用本地方法 2. 作用 释放当前锁&#xff0c;并让当前线程进入等待状态&#xff1b;timeoutMillis为等待时间&#xff0c;单位毫秒&#xff0c;如果为0则表示无限等待下去&#xff1b;该方法使用前提是&#xff1a;当前执行线程必须持…

【开源三方库】Aki:一行代码极简体验JSC++跨语言交互

开源项目 OpenHarmony 是每个人的 OpenHarmony 一、简介 OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;的前端开发语言是ArkTS&#xff0c;在TypeScript&#xff08;简称TS&#xff09;生态基础上做了进一步扩展&#xff0c;继承了TS的所有特性&#x…