使用Java调用Apache commons-text求解字符串相似性实战

目录

前言

一、字符串距离的几种计算方法

1、Levenshtein 距离

2、Overlap Coefficient计算

3、Q-gram Matching

4、余弦相似性计算

二、基于余弦相似性的基地名称对比

1、加载百科中的基地信息列表

2、设置忽略词列表 

3、将数据库地名和Excel进行对比

三、总结


前言

        在之前的一篇漂亮国的全球的基地博客中,我们曾经对漂亮国的全球基地进行了一些梳理。博文中使用的数据来源,重点是参考以为博主分享的KML的数据,同时针对其国内的基地部署信息,我们从互联网百科的数据中搜寻到一些。其实拿到这两份数据的时候,是存在一些问题的,比如,KML的数据它的基地名称都是英文的,而在互联网上公开的数据中,良莠不齐,有的是中文的,有的是英文,有的中英文都有,而且可能还存在同样的英文,它的描述不一样的情况,比如下面的场景:

XXX Air Base 空军基地 

XXX Air Station 航空站

        可能不同的信息来源,其主要的名称对应的真实位置表示的是同一个。再比如漂亮国驻小日子的基地列表。

Idesuna Jima Air Range 

FAC 6078 出砂岛炸射练习场 Idesuna Jima Range 训练 冲绳渡名喜村

        上面一行是从KML中解析出来的基地名称,而下面是从某百科中得到的数据。 当我们将句子的影响词(当出现在军事基地的领域中的某些特定词,如Air、Base、Station、Range等这些词去掉后)其主要的地点就是同一个,通过对比主要关键词的相似性,为我们实现将两个地名进行对齐,甚至可以设定一个阈值,当两个字符串的相似性超过多少(比如超过90%)就认为这是同一个地点,从而可以实现将基地的中文名和所驻地的国家、城市等信息进行一一匹配。从而减少人工对比的工作。

        随着现代技术的快速发展,文本相似度计算有很多种方法,甚至可以用大数据、自然语言处理还可以结合人工智能的方法来实现精确的文本相似性判断。但是本文不想实现那么复杂的架构,只想简单快速的解决两个地址的快速匹配问题。博客以Java编程为例,讲解了在Java中求解两个字符串的几种方法。通过求解编辑距离、Q-gram Matching、还有余弦相似性计算,通过对比不同的方法,调用Apache 的Common-text中基于余弦的字符相似性得到了比较比错的结果。算法比较简单,主要想说明两个字符串的不同距离的计算,对于更复杂的模型,大家感兴趣的可以搜索相关的科研论文来学习。

一、字符串距离的几种计算方法

        为了比较字符的相似性,我们通过通过对比距离(把两个字符串的距离计算出来,当然这个距离的计算是有讲究的,具体的算法就是我们说的距离算法,不同的距离算法,得到的值是不一样的)。因此这里我们打算讲将在Java当中,有哪些距离的计算方法以及如何编写相应的代码。

1、Levenshtein 距离

        计算将一个字符串转换为另一个字符串所需的最少单字符编辑操作(插入、删除或替换)的数量。在下面这个示例中,levenshteinDistance方法使用动态规划来计算两个字符串之间的Levenshtein Distance。calculateNormalizedLevenshteinDistance方法则使用这个距离和两个字符串长度的最大值来计算标准化的Levenshtein Distance。 main方法中给出了两个示例字符串s1和s2,并调用calculateNormalizedLevenshteinDistance方法来计算并打印它们的Normalized Levenshtein Distance。根据这个得分,你可以设定一个阈值来判断两个字符串是否相似。例如,如果Normalized Levenshtein Distance小于0.2(即80%的字符是匹配的),你可以认为这两个字符串是相似的。这个阈值可以根据你的具体需求进行调整。
 

package com.yelang.project;public class NormalizedLevenshteinDistance {// 计算Levenshtein Distancepublic static int levenshteinDistance(String s1, String s2) {int[][] dp = new int[s1.length() + 1][s2.length() + 1];for (int i = 0; i <= s1.length(); i++) {dp[i][0] = i;}for (int j = 0; j <= s2.length(); j++) {dp[0][j] = j;}for (int i = 1; i <= s1.length(); i++) {for (int j = 1; j <= s2.length(); j++) {int cost = (s1.charAt(i - 1) == s2.charAt(j - 1)) ? 0 : 1;dp[i][j] = Math.min(Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + cost);}}return dp[s1.length()][s2.length()];}// 计算Normalized Levenshtein Distancepublic static double calculateNormalizedLevenshteinDistance(String s1, String s2) {int distance = levenshteinDistance(s1, s2);int maxLength = Math.max(s1.length(), s2.length());return (double) distance / maxLength;}public static void main(String[] args) {String s1 = "Camp Humphreys";String s2 = "United States Army Garrison-Humphreys";double normalizedDistance = calculateNormalizedLevenshteinDistance(s1, s2);System.out.println("Normalized Levenshtein Distance: " + normalizedDistance);}
}

        运行上述程序后,得到的结果如下,表示两个字符串的相似度是0.67:

Normalized Levenshtein Distance: 0.6756756756756757

2、Overlap Coefficient计算

        Overlap Coefficient是通过计算两个字符串的最长公共子序列的长度来求两者的相似度的。这种算法有弊有利,在主要的关键词不同而基地的信息完一致的情况下,比如xxx air base 和xx1 air base,通过计算得到的结果一定及其相似,因为这两个字符串的最长公共序列很长啊,计算机看起来就像是完全一致的。

package com.yelang.project;
public class OverlapCoefficient {// 计算最长公共子序列的长度public static int longestCommonSubsequence(String s1, String s2) {int len1 = s1.length();int len2 = s2.length();int[][] dp = new int[len1 + 1][len2 + 1];for (int i = 1; i <= len1; i++) {for (int j = 1; j <= len2; j++) {if (s1.charAt(i - 1) == s2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);}}}return dp[len1][len2];}// 计算Overlap Coefficientpublic static double calculateOverlapCoefficient(String s1, String s2) {int lcsLength = longestCommonSubsequence(s1, s2);int minLength = Math.min(s1.length(), s2.length());return (double) lcsLength / minLength;}public static void main(String[] args) {String s1 = "Camp Humphreys";String s2 = "United States Army Garrison-Humphreys";double overlapCoefficient = calculateOverlapCoefficient(s1, s2);System.out.println("Overlap Coefficient: " + overlapCoefficient);}
}

        运行以上程序后,得到的结果是:

Overlap Coefficient: 0.8571428571428571

        它判定是85%的相似度,貌似看起来比第一种距离很接近真相,你换个词去测试就发现,这种算法其实很蠢。

3、Q-gram Matching

        Q-gram Matching是一种基于子串的字符串相似度计算方法,其中Q表示子串的长度。对于两个字符串,计算它们共有的Q-gram(长度为Q的连续子串)的数量,然后将这个数量除以两个字符串中Q-gram数量较少的那个, 得到相似度的比例。下面给出它的Java实现:

package com.yelang.project;
import java.util.HashSet;
import java.util.Set;
public class QGramMatching {/*** 在这个示例中,calculateQGrams方法接受一个字符串和一个整数Q,然后返回该字符串所有可能的Q-gram的集合。calculateQGramSimilarity方法接受两个字符串和一个整数Q,计算它们的Q-gram集合,并找出共有的Q-gram数量,然后计算相似度。main方法中给出了两个示例字符串s1和s2,以及Q-gram的长度Q,并调用calculateQGramSimilarity方法来计算并打印它们的Q-gram相似度。请注意,Q-gram的长度Q是一个参数,可以根据具体应用场景进行调整。较短的Q值可以捕捉到更细粒度的相似性,而较长的Q值则可以捕捉到更宽泛的相似性。此外,相似度的阈值可以根据实际需求设定,以判断两个字符串是否相似。*/// 计算字符串的Q-gram集合public static Set<String> calculateQGrams(String s, int q) {Set<String> qGrams = new HashSet<>();for (int i = 0; i <= s.length() - q; i++) {qGrams.add(s.substring(i, i + q));}return qGrams;}// 计算两个字符串的Q-gram相似度public static double calculateQGramSimilarity(String s1, String s2, int q) {Set<String> qGrams1 = calculateQGrams(s1, q);Set<String> qGrams2 = calculateQGrams(s2, q);// 计算两个集合的交集Set<String> intersection = new HashSet<>(qGrams1);intersection.retainAll(qGrams2);// 计算相似度double similarity = intersection.size() / (double) Math.min(qGrams1.size(), qGrams2.size());return similarity;}public static void main(String[] args) {String s1 = "Camp Humphreys";String s2 = "United States Army Garrison-Humphreys";// Misawa Air Range<==>Misawa Air Base:similar = 0.9058216273156766// Gun Training Area<==>Tsuken Jima Training Area:similar = 0.9202830114233174int q = 3; // Q-gram的长度double qGramSimilarity = calculateQGramSimilarity(s1, s2, q);System.out.println("Q-gram Similarity (Q=" + q + "): " + qGramSimilarity);}
}

        运行以上的程序,得到以下的执行结果:

Q-gram Similarity (Q=3): 0.5833333333333334

4、余弦相似性计算

        使用词嵌入(如word2vec或BERT)将单词转换为向量,并计算向量之间的余弦相似度。这里基于Apache 的common-text来进行余弦计算,看结果如何,首先在Pom.xml中引入以下资源。

<!-- 求解字符相似性 -->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-text</artifactId><version>1.10.0</version>
</dependency>

        然后在Java中实现以下方法,请注意,这里是一种比较简单的方法,更精准的实现还要结合实际场景进行优化。

/**
*计算两个字符串的相似性
* @param args1
* @param args2
* @return
*/
private Double getSimilar(String args1,String args2) {Map<CharSequence, Integer> map = Arrays.stream(args1.split("")).collect(Collectors.toMap(c -> c, c -> 1, Integer::sum));Map<CharSequence, Integer> map2 = Arrays.stream(args2.split("")).collect(Collectors.toMap(c -> c, c -> 1, Integer::sum));CosineSimilarity cosineSimilarity = new CosineSimilarity();Double similar = cosineSimilarity.cosineSimilarity(map, map2);return similar;
}

        基于余弦的方法运行结果:

similar = 0.6726637889454885

        篇幅有限,这里不做很全面的覆盖测试,基于上面的代码,感兴趣的朋友和同学可以自己去做测试,根据不同的样例,得到的结果阈值比较令人想象不到,建议结合真实的数据进行测试,你会发现问题更大。如果要把这个应用于实战的话,建议不要采用上述模型,推荐采用TF-IDF(Term Frequency-Inverse Document Frequency)和余弦计算的方式。最后进行综合评分,将不同的相似度计算方法(如基于编辑的算法、基于令牌的方法、基于语义的方法)结合起来,并为每种方法分配一个权重,然后计算加权平均值。这样子计算出来的结果比较准确。更深入的内容,大家闲暇的时候可以自主实现。

二、基于余弦相似性的基地名称对比

        这里我们讲解如何把数据库中的基地列表信息和通过Excel表格整理的基地信息进行综合对比,通过余弦相似性和设置忽略词来提高准确度。作为一种参考的实现方案供大家参考。

1、加载百科中的基地信息列表

        要想将数据库中的基地信息和百科中的数据进行对比,首先要做的就是数据采集。通过把从百科采集的数据转换成excel,然后应用程序解析Excel数据,通过计算计算英文名称的相似性来进行对比。基础数据采集的方式,可以根据大家的熟悉程度,可以通过爬虫的形式进行介绍,也可以把表格直接复制到Exclel,直接进行Excle的读取成List列表后进行对比即可。这里我们以第二种方案来进行讲解。以下是从百科中节选的Excel中的数据列表。

管理设施代码基地英文名称基地中文名称用途驻地国家中文名驻地国家英文名驻地城市中文名
FAC 1054Camp Chitose千岁营通信日本Japan北海道千岁市
FAC 2001Misawa Air Base三泽空军基地航空基地日本Japan青森县三泽市
FAC 3013Yokota Air Base横田空军基地航空基地日本Japan东京都福生市
FAC 3016Fuchu Communications Station府中通讯站通信日本Japan东京都府中市
FAC 3019Tama Hills Recreation Center多摩之丘育乐中心娱乐日本Japan东京都稻城市
FAC 3048South Camp Drake AFN Transmitter Site南德雷克营美军电台转播站兵营日本Japan埼玉县和光市
FAC 3048Camp Asaka朝霞营兵营日本Japan埼玉县和光市
FAC 3049Tokorozawa Communications Station所泽通讯站通信日本Japan埼玉县所泽市
FAC 3056Owada Communication Site大和田通讯站通信日本Japan埼玉新座市
FAC 3162Yugi Communication Site由木通讯站通信日本Japan东京都八王子市
FAC 4100Sofu Communication Site祖生通讯站通信日本Japan山口县岩国市
FAC 5001Itazuke Auxiliary Airfield板付辅助飞行场空运货站日本Japan福冈市博多区
FAC 5073Sefurisan Liaison Annex脊振山辅助联络站通信日本Japan佐贺县神埼市
FAC 5091Tsushima Communication Site对马通讯站通信日本Japan长崎对马市
FAC 6004Okuma Rest Center奥间休息中心娱乐日本Japan冲绳国头村
FAC 6006Yaedake Communication Site八重岳通讯站通信日本Japan冲绳本部町
FAC 6022Kadena Ammunition Storage Area嘉手纳弹药储存区存储日本Japan冲绳恩纳村
FAC 6037Kadena Air Base嘉手纳空军基地航空基地日本Japan冲绳嘉手纳
FAC 6077Tori Shima Range鸟岛炸射练习场训练日本Japan冲绳久米岛
FAC 6078Idesuna Jima Range出砂岛炸射练习场训练日本Japan冲绳渡名喜村
FAC 6080Kume Jima Range久米岛炸射练习场训练日本Japan冲绳久米岛町
FAC 2070Shariki Communication Site车力通讯站通信日本Japan青森县津轻市
FAC 3004Akasaka Press Center (Hardy Barracks)赤坂新闻中心(哈迪军营)办公室日本Japan东京都港区
FAC 3067Yokohama North Dock横滨北坞港口设施日本Japan神奈川县横滨市

        上面只是一个示例,实际的表格有85条数据。

         我们需要将Excel中的数据进行导入到应用程序中,首先需要定义一个实体类:

package com.yelang.project.extend.militarytopics.domain;
import java.io.Serializable;
import com.yelang.framework.aspectj.lang.annotation.Excel;
import com.yelang.framework.aspectj.lang.annotation.Excel.Type;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class WebSiteMilitaryBase implements Serializable{private static final long serialVersionUID = -4620277223946004351L;@Excel(name = "设施管理代码", type = Type.IMPORT)private String manageCode;@Excel(name = "基地英文名称")private String enName;@Excel(name = "基地中文名称")private String cnName;@Excel(name = "用途")private String useTo;@Excel(name = "驻地国家中文名")private String cnCountry;@Excel(name = "驻地国家英文名")private String enCountry;@Excel(name = "驻地城市中文名")private String cnCity;
}

        然后定义Excel的读取方法,关键代码如下所示:

public void readJapanData() {try {File file = new File("C:/Users/Administrator/Desktop/基地/驻日美军基地.xlsx");FileInputStream fis = new FileInputStream(file);ExcelUtil<WebSiteMilitaryBase> util = new ExcelUtil<WebSiteMilitaryBase>(WebSiteMilitaryBase.class);List<WebSiteMilitaryBase> dataList = util.importExcel(fis);System.out.println(dataList.size());for(WebSiteMilitaryBase base : dataList) {System.out.println(base);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}
}

        运行一下代码,测试一下是否读取成功,如果在控制台中看到以下信息说明解析成功。

2、设置忽略词列表 

        其实忽略词和权重打分的作用是差不多的,忽略词就是在字符串中没有什么影响的词,这里需要注意的是要结合场景来说明。比如当前是均事领域,类似与Air base等这些在相关基地中的字符串中就可以忽略掉。忽略词设置好之后,在进行字符串的相似性计算时,需要把两个字符串进行忽略词替换。关键代码如下:

/**
* 去掉需要忽略的关键词
* @param source
* @return
*/
private String ignoreKeyWords(String source) {// Barracks 军营 Service Area 服务中心  Air Station 航空站 Air Base 空军基地 Camp 营地 Recreation Center 娱乐中心 Communications Station 通信站// Transmitter Site 发射站 Communication Site 通信站点 Training 训练 Airfield机场 Ammunition Depot 弹药库 Port 港口 Pier 码头 Dependent Housing 家属区// Depot 仓库 Landing Field 着陆场 Corps 兵团 Naval 海军String [] keyWords = {"Barracks","Service Area","Station","Air","Base","Camp","Area","Recreation Center","Communications","Station","Transmitter","Site","Communication","Training","Airfield","Annex","Ammunition","Port","Pier","Dependent","Housing","Depot","Storage","Range","Center","Landing Field","Corps","Naval","Marine"};for(String keyword : keyWords) {source = source.replace(keyword, "").trim();}return source;
}

3、将数据库地名和Excel进行对比

        在这里 ,我们需要将需要对比的数据从数据库中查询出来,然后跟Excel表格中的进行对比。经过忽略词的设置后,我们对比最后的计算结果,最后得到两个字符串的相似性。当两个字符串的相似度大于90%,我们即可认为是统一地点,当然这里最好需要人工审核。

@Test
public void evalJapanCosineSimilarity() {QueryWrapper<UsaMilitaryBase> queryWrapper = new QueryWrapper<UsaMilitaryBase>();queryWrapper.isNull("cn_name");//查询基地中文名为空的数据List<UsaMilitaryBase> dbList = this.militaryBaseService.list(queryWrapper);System.out.println(dbList.size());try {File file = new File("C:/Users/Administrator/Desktop/基地/驻日美军基地.xlsx");FileInputStream fis = new FileInputStream(file);ExcelUtil<WebSiteMilitaryBase> util = new ExcelUtil<WebSiteMilitaryBase>(WebSiteMilitaryBase.class);List<WebSiteMilitaryBase> excelDataList = util.importExcel(fis);System.out.println(excelDataList.size());int index = 0;for(WebSiteMilitaryBase base : excelDataList) {for(UsaMilitaryBase dbBase : dbList) {String dbEnName = dbBase.getEnName();dbEnName = ignoreKeyWords(dbEnName);String excelEnName = base.getEnName();excelEnName = ignoreKeyWords(excelEnName);Double similar = this.getSimilar(dbEnName, excelEnName);if(similar >= 0.85) {System.out.println(dbEnName + "<==>" + excelEnName + "\t similar = " + similar);System.out.println(base);index ++;}else {continue;}}}System.out.println(index);} catch (FileNotFoundException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}
}

        下面我们来执行上述的代码,看看最终符合我们条件的有多少?

 

Misawa<==>Misawa	 similar = 0.9999999999999998
WebSiteMilitaryBase(manageCode=FAC 2001, enName=Misawa Air Base, cnName=三泽空军基地, useTo=航空基地, cnCountry=日本, enCountry=Japan, cnCity=青森县三泽市)
Idesuna Jima<==>Idesuna Jima	 similar = 1.0
WebSiteMilitaryBase(manageCode=FAC 6078, enName=Idesuna Jima Range, cnName=出砂岛炸射练习场, useTo=训练, cnCountry=日本, enCountry=Japan, cnCity=冲绳渡名喜村)
Kawakami<==>Kawakami	 similar = 1.0
WebSiteMilitaryBase(manageCode=FAC 4083, enName=Kawakami Ammunition Depot, cnName=川上弹药库, useTo=存储, cnCountry=日本, enCountry=Japan, cnCity=广岛县东广岛市)
Hiro<==>Hiro	 similar = 1.0
WebSiteMilitaryBase(manageCode=FAC 4084, enName=Hiro Ammunition Depot, cnName=广弹药库, useTo=存储, cnCountry=日本, enCountry=Japan, cnCity=广岛县吴市)
Kure  6<==>Kure  No.6	 similar = 0.8660254037844386
WebSiteMilitaryBase(manageCode=FAC 4152, enName=Kure Pier No.6, cnName=吴市6号码头, useTo=港口设施, cnCountry=日本, enCountry=Japan, cnCity=广岛县吴市)
Torii<==>Torii	 similar = 0.9999999999999999
WebSiteMilitaryBase(manageCode=FAC 6036, enName=Torii Communications Station, cnName=鸟居通讯站, useTo=通信, cnCountry=日本, enCountry=Japan, cnCity=冲绳县读谷村)
Naha<==>Naha	 similar = 1.0000000000000002
WebSiteMilitaryBase(manageCode=FAC 6064, enName=Naha Port, cnName=那霸港湾设施, useTo=港口设施, cnCountry=日本, enCountry=Japan, cnCity=冲绳县那霸市)
Fleet Activities Chinhae KS<==>United States Fleet Activities Yokosuka	 similar = 0.8653323061113575
WebSiteMilitaryBase(manageCode=FAC 3099, enName=United States Fleet Activities Yokosuka, cnName=横须贺美国舰队基地, useTo=港口设施, cnCountry=日本, enCountry=Japan, cnCity=神奈川县横须贺市)
Fleet Activities Chinhae KS (Yechon)<==>United States Fleet Activities Sasebo	 similar = 0.8560516500077061
WebSiteMilitaryBase(manageCode=FAC 5029, enName=United States Fleet Activities Sasebo, cnName=佐世保美国舰队基地, useTo=港口设施, cnCountry=日本, enCountry=Japan, cnCity=长崎县佐世保市)
Fleet Activities Chinhae KS<==>United States Fleet Activities Sasebo	 similar = 0.8994681014529727
WebSiteMilitaryBase(manageCode=FAC 5029, enName=United States Fleet Activities Sasebo, cnName=佐世保美国舰队基地, useTo=港口设施, cnCountry=日本, enCountry=Japan, cnCity=长崎县佐世保市)
Hiro<==>Hario	 similar = 0.8944271909999159
WebSiteMilitaryBase(manageCode=FAC 5119, enName=Hario Dependent Housing Area, cnName=针尾军眷住宅区, useTo=住宅, cnCountry=日本, enCountry=Japan, cnCity=长崎县佐世保市)
Fleet Activities Chinhae KS (Yongsan Garrison)<==>Makiminato  ( Kinser)	 similar = 0.8663164754169591
WebSiteMilitaryBase(manageCode=FAC 6056, enName=Makiminato Service Area (Camp Kinser), cnName=牧港补给地区(金瑟营), useTo=后勤, cnCountry=日本, enCountry=Japan, cnCity=冲绳县浦添市)
San Vito Dei Normanni<==>Makiminato  ( Kinser)	 similar = 0.8524007579586305
WebSiteMilitaryBase(manageCode=FAC 6056, enName=Makiminato Service Area (Camp Kinser), cnName=牧港补给地区(金瑟营), useTo=后勤, cnCountry=日本, enCountry=Japan, cnCity=冲绳县浦添市)
13

      可以很直观的看到,经过计算,有的地名已经完全匹配,比如Hiro<==>Hiro     similar = 1.0和Idesuna Jima<==>Idesuna Jima     similar = 1.0。这些数据可以认为是一个地点了。

三、总结

        以上就是本文的主要内容,博客以Java编程为例,讲解了在Java中求解两个字符串的几种方法。通过求解编辑距离、Q-gram Matching、还有余弦相似性计算,通过对比不同的方法,调用Apache 的Common-text中基于余弦的字符相似性得到了比较比错的结果。最后讲解了一个实际的案例,将之前我们采集的漂亮数据库数据和百科的数据进行对齐。为下一步做数据关联和挖掘打下坚实的基础。行文仓促,定有许多的不足之处,如有任何不当或者表达不准确的地方,还恳请各位专家和朋友在评论区留言平指正,不胜感激。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从力扣中等+困难题+表白HTML测试 -- 文心快码(Baidu Comate)

0 写在前面 官网地址&#xff1a;Baidu Comate Step1 打开文心快码&#xff08;Baidu Comate&#xff09;官网&#xff0c;点击「免费使用」/「下载安装」 Step2 可以根据官网步骤快速唤起VS Code&#xff1b; 也可以直接在VS Code、Visual Studio扩展管理搜索“文心快码”/…

如何用OceanBase实现HBase架构升级

随着数据量的爆炸性增长&#xff0c;特别是半结构化和非结构化数据的涌现&#xff0c;传统关系型数据库如 MySQL 遭遇了前所未有的挑战。这一背景下&#xff0c;为非结构化数据管理而生的 NoSQL 数据库&#xff0c;以及旨在解决海量数据存储难题的分布式技术应运而生&#xff0…

导出word格式的Javadoc(可用于快速生成项目详细设计文档)

导出word格式的Javadoc ​ 最近要编写项目详细设计文档&#xff0c;作为程序员当然想看看有没有能够自动生成的办法&#xff0c;生成详细设计文档&#xff0c;然后再在生成的基础上略做修改就好了&#xff08;偷懒大法~&#xff09;&#xff0c;还真有&#xff0c;特此分享&am…

理解Pytorch中的collate_fn函数

PyTorch中的DataLoader是最常用的类之一&#xff0c;这个类有很多参数&#xff08;14 个&#xff09;&#xff0c;但大多数情况下&#xff0c;你可能只会使用其中的三个&#xff1a;dataset、shuffle 和 batch_size。其中collate_fn是比较少用的函数&#xff0c;这对初学者来说…

Linux线程间通信学习记录(线程同步)

0.线程间通信的方法 &#xff08;1&#xff09;.全局变量&#xff08;要结合同步机制&#xff09; &#xff08;2&#xff09;.信号量 &#xff08;3&#xff09;.P操作 &#xff08;4&#xff09;.V操作 一.线程同步 同步&#xff1a;指的是多个任务按照约定的先后次序相互…

Visual C++ 2010 学习版

这个版本很好用。 在这里放一个链接&#xff0c;做个备份。 这个版本是承前启后的版本&#xff0c;非常的重要。 一、使用VC2010 这个版本创建的解决方案可以在VS2010~VS2022版本中打开&#xff0c;反之也行。 二、使用VC2010 可以编绎VC6.0 ~VC2008的项目。可以使用现成的…

灵办AI助手Chrome插件全面评测:PC Web端的智能办公利器

探索灵办AI助手在Mac OS上的高效表现&#xff0c;支持多款主流浏览器&#xff0c;助你轻松应对办公挑战 文章目录 探索灵办AI助手在Mac OS上的高效表现&#xff0c;支持多款主流浏览器&#xff0c;助你轻松应对办公挑战摘要引言开发环境介绍核心功能评测1. 网页翻译与双语对照 …

Rancher 使用 Minio 备份 Longhorn 数据卷

0. 概述 Longhorn 支持备份到 NFS 或者 S3, 而 MinIO 就是符合 S3 的对象存储服务。通过 docker 部署 minio 服务&#xff0c;然后在 Longhorn UI 中配置备份服务即可。 1. MinIO 部署 1.1 创建备份目录 mkdir -p /home/longhorn-backup/minio/data mkdir -p /home/longhor…

RCE的另外一些绕过练习

目录 被过滤了flag怎么办 方法 结果 过滤了flag、php、system 方法一 结果 ​编辑 方法二 过滤了很多但是主要的就是过滤了空格 和 注意一下这个就行 方法一 方法二 相对于上面一道题来说多过滤了一个括号 方法一 被过滤了flag怎么办 <?php error_reportin…

Python3网络爬虫开发实战(10)模拟登录(需补充账号池的构建)

文章目录 一、基于 Cookie 的模拟登录二、基于 JWT 模拟登入三、账号池四、基于 Cookie 模拟登录爬取实战五、基于JWT 的模拟登录爬取实战六、构建账号池 很多情况下&#xff0c;网站的一些数据需要登录才能查看&#xff0c;如果需要爬取这部分的数据&#xff0c;就需要实现模拟…

K8S - ConfigMap的简介和使用

什么是configMap Kubernetes中的ConfigMap 是用于存储非敏感数据的API对象&#xff0c;用于将配置数据与应用程序的镜像分离。ConfigMap可以包含键值对、文件或者环境变量等配置信息&#xff0c;应用程序可以通过挂载ConfigMap来访问其中的数据&#xff0c;从而实现应用配置的…

ubuntu20 lightdm无法自动登录进入桌面

现象&#xff1a;在rk3568的板子上自己做了一个Ubuntu 20.04的桌面系统。配置lightdm自动登录桌面&#xff0c;配置方法如下&#xff1a; $ vim /etc/lightdm/lightdm.conf [Seat:*] user-sessionxubuntu autologin-userusername #修改成自动登录的用户名 greeter-show-m…

38-PCB布局实战实战及优化

1.先对布局好的器件进行锁定 1.根据模块化布局 2.电容尽量靠近ic附近&#xff0c;可以起到很好的滤波效果 3.复位按键尽量摆在容易按键的地方&#xff0c;比如周围 。。。。 最后进行对齐

【OCR 学习笔记】二值化——局部阈值方法

二值化——局部阈值方法 自适应阈值算法Niblack算法Sauvola算法 自适应阈值算法 自适应阈值算法1用到了积分图&#xff08;Integral Image&#xff09;的概念。积分图中任意一点 ( x , y ) (x,y) (x,y)的值是从图左上角到该点形成的矩形区域内所有值的和。即&#xff1a; I (…

模板[C++]

目录 1.&#x1f680;泛型编程&#x1f680; 2.&#x1f680;函数模板&#x1f680; 2.1 ✈️函数模板概念✈️ 2.2 ✈️函数模板格式✈️ 2.3✈️函数模板的原理✈️ 2.4 ✈️函数模板的实例化✈️ 2.5 ✈️模板参数的匹配原则✈️ 3.&#x1f680;类模板&#x1f680…

文件中找TopK问题 的详细讲解

一&#xff1a;问题&#xff1a; 从一个包含10000整数的文件中找出最大的前10个数。 二&#xff1a;方法&#xff1a; 1&#xff1a;先直接拿文件的前10个数&#xff0c;建造一个小堆 2&#xff1a;再依次读取文件中&#xff0c;剩下的数&#xff0c;比堆顶大&#xff0c;则…

学习记录第二十九天

信号量————来描述可使用资源的个数 信号量&#xff08;Semaphore&#xff09;是一种用于控制多个进程或线程对共享资源访问的同步机制。在C语言中&#xff0c;通常我们会使用POSIX线程&#xff08;pthread&#xff09;库来实现信号量的操作 信号量有两个主要操作&#xf…

C语言 ——— 位段(位域)

目录 什么是位段 位段的内存分配 什么是位段 位段的声明和结构体是类似的 但有两个不同&#xff1a; 1. 位段的成员必须是整型家族&#xff1a; int&#xff08;整型&#xff09; &#xff0c;unsigend int &#xff08;无符号整型&#xff09;&#xff0c;sigend int&…

【初阶数据结构题目】32. 希尔排序

文章目录 希尔排序希尔排序的时间复杂度计算 希尔排序 希尔排序法又称缩小增量法。希尔排序法的基本思想是&#xff1a;先选定一个整数&#xff08;通常是gap n/31&#xff09;&#xff0c;把待排序文件所有记录分成各组&#xff0c;所有的距离相等的记录分在同一组内&#x…

歌曲爬虫下载

本次编写一个程序要爬取歌曲音乐榜https://www.onenzb.com/ 里面歌曲。有帮到铁子的可以收藏和关注起来&#xff01;&#xff01;&#xff01;废话不多说直接上代码。 1 必要的包 import requests from lxml import html,etree from bs4 import BeautifulSoup import re impo…