Lucene从入门到精通

****************************************************************************************************************************************************************************

1、概述
【1】入门:作用、有点与缺点
【2】应用:索引、搜索、field域使用、索引库、分词器、高级搜岁实战
【3】高级:底层存储结构、词典排序算法、优化、使用的一些使用注意事项

****************************************************************************************************************************************************************************

2、Lucene的作用
【1】用户—>服务器—>Lucene API—>索引库—>数据库/文档/web网页—>再返回。

****************************************************************************************************************************************************************************

3、常用的查询算法
【1】顺序扫描法:(数据量大的时候就GG),mysql的like查询就是,文本编辑器的Ctrl+F。
【2】倒排索引:把文章提取出来—>文档(正文)—>切分词组成索引目录。查询的时候先查目录,然后再找正文。切分词是个关键。
为什么倒排索引快?去掉重复的词,去掉停用词(的、地、得、a、an、the)。查字词典肯定比文章少。字典原理所以快。
优点:准确率高、速度快。但是空间占用量肯定会大,时间与空间不能兼得。它是用空间换时间。额外占用磁盘空间来存储目录。

****************************************************************************************************************************************************************************

5、全文检索技术使用场景
【1】站内搜索(百度贴吧、京东、淘宝)。垂直领域的搜索(818工作网)。专业搜索引擎(谷歌、百度)

****************************************************************************************************************************************************************************

6、什么是Lucene
【1】文章—>词—>索引(目录)
【2】全文检索:查先查目录,再查文本,这就是全文检索。
【3】Doug Cutting是Lucene、Nutch、Hadoop等项目的发起人。捐献给了Apache基金会。
【4】官网 https://lucene.apache.org

****************************************************************************************************************************************************************************

7、索引和搜索流程概述
【1】原始文档—>创建索引(获得文档-构建文档对象-分词-创建索引)—>索引库(肯定是提前创建)。
【2】用户查询—>创建查询—>执行查询—>渲染结果—>返回结果。

****************************************************************************************************************************************************************************

8、Lucene索引流程详细
【1】Document文档(唯一ID)。Field域(key value的形式)。id:1 name:华为手机64G brandName:华为。id:2 name:华为手机128G brandName:华为
【2】会根据text提取分词,分析后得到的词:....................。关键词 1 在文档1,关键词2 在文档2 ,关键词手机 在文档1&文档2。这种方式存储。
【3】然后先找到关键词在哪个文档,然后再去对应文档查,有道理呀。卧槽

****************************************************************************************************************************************************************************

9、Lucene搜索流程详细
【1】华为手机,看是华为 AND 手机,还是华为 OR 手机。来决定查询结果

****************************************************************************************************************************************************************************

10、Lucene入门
【1】jar包下载配置
  <!--Lucene****************************************************************************************************************************************************-->
        <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-highlighter -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-highlighter</artifactId>
            <version>7.7.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-queryparser -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
            <version>7.7.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-analyzers-smartcn -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-smartcn</artifactId>
            <version>7.7.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-analyzers-common -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
            <version>7.7.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-core -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>7.7.2</version>
        </dependency>

****************************************************************************************************************************************************************************

13、创建索引
【1】具体创建代码
  public static void createIndex() throws Exception {
        // 1.采集数据
        Product product_1 = new Product(1, "华为手机", 3000, 10, "华为.jpg", "华为", "300*300", 5);
        Product product_2 = new Product(2, "苹果手机", 8000, 30, "苹果.jpg", "苹果", "500*500", 15);
        List<Product> productList = new ArrayList<>();
        productList.add(product_1);
        productList.add(product_2);

        List<Document> documentList = new ArrayList<>(); // 文档集合
        // 2.创建文档对象
        for (Product temp : productList) {
            // 创建文档
            Document document = new Document();
            // 创建域对象,并且放到文档对象中
            document.add(new TextField("id", temp.getId() + "", Field.Store.YES));
            document.add(new TextField("name", temp.getName(), Field.Store.YES));
            document.add(new TextField("price", temp.getPrice() + "", Field.Store.YES));
            document.add(new TextField("num", temp.getNum() + "", Field.Store.YES));
            document.add(new TextField("image", temp.getImage() + "", Field.Store.YES));
            document.add(new TextField("brandName", temp.getBrandName() + "", Field.Store.YES));
            document.add(new TextField("spec", temp.getSpec() + "", Field.Store.YES));
            // 放到文档集合
            documentList.add(document);
        }
        // 3.创建分词器
        Analyzer analyzer = new StandardAnalyzer();
        // 4.创建index目录对象,目录对象表示索引库的位置
        Directory directory = FSDirectory.open(Paths.get("src/main/resources/index"));
        // 5.创建IndexWriterConfig对象, 这个对象指定切分词使用的分词器
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
        // 6.创建IndexWriter输出流对象,指定输出位置和使用的config初始化对象。
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);
        // 7.写入文档到索引库
        for (Document temp : documentList) {
            indexWriter.addDocument(temp);
        }
        // 8.释放资源
        indexWriter.close();
    }

****************************************************************************************************************************************************************************

14、查看索引详情工具
【1】https://github.com/DmitryKey/luke/tree/luke-swing-8.0.0/src/main/java/org/apache/lucene/luke/app/desktop直接下载运行
【2】Luke工具的使用,很重要的!!!!!!!!!!!!

****************************************************************************************************************************************************************************

15、搜索索引
【1】实际代码
// 二、搜索
    public static void searchIndex() throws Exception {
        // 1.创建分词器(对搜索的内容进行分词使用)。如华为手机可能拆分为 华为 手机
        Analyzer analyzer = new StandardAnalyzer();
        // 注意!!!:分词器要和创建索引的时候使用的分词器一模一样(不然搜索的时候就有问题)
        // 2.创建查询对象  // 第一个arg默认查询域   //
        QueryParser queryParser = new QueryParser("name", analyzer);
        // 3.设置搜索关键词
        Query query = queryParser.parse("华为"); // queryParser.parse("id:华为手机") 指定从id查,不指定就从默认的name域查
        // 4.设置Directory目录对象,指定索引库的位置
        Directory directory = FSDirectory.open(Paths.get("src/main/resources/index"));
        // 5.创建输入流对象
        IndexReader indexReader = DirectoryReader.open(directory);
        // 6.创建搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        // 7.搜索并返回结果
        TopDocs topDocs_10 = indexSearcher.search(query, 10);
        // 8.获取结果集
        ScoreDoc[] scoreDocArray = topDocs_10.scoreDocs;
        // 9.遍历结果集
        System.out.println("共查询到 " + scoreDocArray.length + " 条数据");
        if (scoreDocArray != null) {
            for (ScoreDoc temp : scoreDocArray) {
                // 获取查询到的文档唯一ID,这个ID是Lucene在创建文档的时候自动分配的。
                int docId = temp.doc;
                // 通过文档ID读取文档
                Document document = indexSearcher.doc(docId);
                System.out.println("******************************************************************************************************");
                System.out.println("id: " + document.get("id"));
                System.out.println("name: " + document.get("name"));
                System.out.println("price: " + document.get("price"));
            }
        }
        // 10. 关闭流
        indexReader.close();
    }

****************************************************************************************************************************************************************************

16、Field域的使用
【1】Field类:索引的目的是为了查询。比如商品ID、订单号、身份证号这个不用分词。凡是用来展示的都需要存储。
【2】所以每个属性都要进行是否分词、是否索引、是否存储的改造。
  // 2.创建文档对象
        for (Product temp : productList) {
            // 创建文档
            Document document = new Document();
            // 创建域对象,并且放到文档对象中
            document.add(new TextField("id", temp.getId() + "", Field.Store.YES));// 否 是 是(是为了查数据库)
            document.add(new TextField("name", temp.getName(), Field.Store.YES));// 是 是 是(因为页面需要展示商品名称)
            document.add(new IntPoint("price", temp.getPrice()));// 是(底层的逻辑) 是(根据范围查询) 是
            document.add(new StoredField("price", temp.getPrice()));// 与上面组合来完成存储
            document.add(new TextField("num", temp.getNum() + "", Field.Store.YES));
            document.add(new TextField("image", temp.getImage() + "", Field.Store.YES));
            document.add(new TextField("brandName", temp.getBrandName() + "", Field.Store.YES));  // 否 是 是
            document.add(new TextField("spec", temp.getSpec() + "", Field.Store.YES));
            // 放到文档集合
            documentList.add(document);
        }

****************************************************************************************************************************************************************************

17、索引库维护
【1】如果数据库数据变了,索引库里怎么同步?
package com.day;


import com.day.pojo.Product;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

// 主函数入口
public class DayApplication {
    public static void main(String[] args) throws Exception {
        //createIndex();
        //searchIndex();
        //updateIndex();
        deleteIndex();
    }

    // 一、创建索引
    public static void createIndex() throws Exception {
        // 1.采集数据
        Product product_1 = new Product(1, "华为手机", 3000, 10, "华为.jpg", "华为", "300*300", 5);
        Product product_2 = new Product(2, "苹果手机", 8000, 30, "苹果.jpg", "苹果", "500*500", 15);
        List<Product> productList = new ArrayList<>();
        productList.add(product_1);
        productList.add(product_2);

        List<Document> documentList = new ArrayList<>(); // 文档集合
        // 2.创建文档对象
        for (Product temp : productList) {
            // 创建文档
            Document document = new Document();
            // 创建域对象,并且放到文档对象中
            document.add(new TextField("id", temp.getId() + "", Field.Store.YES));// 否 是 是(是为了查数据库)
            document.add(new TextField("name", temp.getName(), Field.Store.YES));// 是 是 是(因为页面需要展示商品名称)
            document.add(new IntPoint("price", temp.getPrice()));// 是(底层的逻辑) 是(根据范围查询) 是
            document.add(new StoredField("price", temp.getPrice()));// 与上面组合来完成存储
            document.add(new TextField("num", temp.getNum() + "", Field.Store.YES));
            document.add(new TextField("image", temp.getImage() + "", Field.Store.YES));
            document.add(new StringField("brandName", temp.getBrandName() + "", Field.Store.YES)); // 否 是 是
            document.add(new TextField("spec", temp.getSpec() + "", Field.Store.YES));
            // 放到文档集合
            documentList.add(document);
        }
        // 3.创建分词器
        Analyzer analyzer = new StandardAnalyzer();
        // 4.创建index目录对象,目录对象表示索引库的位置
        Directory directory = FSDirectory.open(Paths.get("src/main/resources/index"));
        // 5.创建IndexWriterConfig对象, 这个对象指定切分词使用的分词器
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
        // 6.创建IndexWriter输出流对象,指定输出位置和使用的config初始化对象。
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);
        // 7.写入文档到索引库
        for (Document temp : documentList) {
            indexWriter.addDocument(temp);
        }
        // 8.释放资源
        indexWriter.close();
    }

    // 二、搜索
    public static void searchIndex() throws Exception {
        // 1.创建分词器(对搜索的内容进行分词使用)。如华为手机可能拆分为 华为 手机
        Analyzer analyzer = new StandardAnalyzer();
        // 注意!!!:分词器要和创建索引的时候使用的分词器一模一样(不然搜索的时候就有问题)
        // 2.创建查询对象  // 第一个arg默认查询域   //
        QueryParser queryParser = new QueryParser("name", analyzer);
        // 3.设置搜索关键词
        Query query = queryParser.parse("华为"); // queryParser.parse("id:华为手机") 指定从id查,不指定就从默认的name域查
        // 4.设置Directory目录对象,指定索引库的位置
        Directory directory = FSDirectory.open(Paths.get("src/main/resources/index"));
        // 5.创建输入流对象
        IndexReader indexReader = DirectoryReader.open(directory);
        // 6.创建搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        // 7.搜索并返回结果
        TopDocs topDocs_10 = indexSearcher.search(query, 10);
        // 8.获取结果集
        ScoreDoc[] scoreDocArray = topDocs_10.scoreDocs;
        // 9.遍历结果集
        System.out.println("共查询到 " + scoreDocArray.length + " 条数据");
        if (scoreDocArray != null) {
            for (ScoreDoc temp : scoreDocArray) {
                // 获取查询到的文档唯一ID,这个ID是Lucene在创建文档的时候自动分配的。
                int docId = temp.doc;
                // 通过文档ID读取文档
                Document document = indexSearcher.doc(docId);
                System.out.println("******************************************************************************************************");
                System.out.println("id: " + document.get("id"));
                System.out.println("name: " + document.get("name"));
                System.out.println("price: " + document.get("price"));
            }
        }
        // 10. 关闭流
        indexReader.close();
    }

    // 三、修改索引
    public static void updateIndex() throws Exception {
        // 1.需要变更成的内容
        Document document = new Document();
        // 创建域对象,并且放到文档对象中
        document.add(new TextField("id", "110161", Field.Store.YES));// 否 是 是(是为了查数据库)
        document.add(new TextField("name", "魅族手机", Field.Store.YES));// 是 是 是(因为页面需要展示商品名称)
        document.add(new IntPoint("price", 1000));// 是(底层的逻辑) 是(根据范围查询) 是
        document.add(new StoredField("price", 1000));// 与上面组合来完成存储

        // 3.创建分词器
        Analyzer analyzer = new StandardAnalyzer();
        // 4.创建index目录对象,目录对象表示索引库的位置
        Directory directory = FSDirectory.open(Paths.get("src/main/resources/index"));
        // 5.创建IndexWriterConfig对象, 这个对象指定切分词使用的分词器
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
        // 6.创建IndexWriter输出流对象,指定输出位置和使用的config初始化对象。
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);
        // 7.修改文档
        indexWriter.updateDocument(new Term("id", "1"), document);
        // 8.释放资源
        indexWriter.close();
    }

    // 四、删除索引,慎用(根据条件删除)
    public static void deleteIndex() throws Exception {
        // 3.创建分词器
        Analyzer analyzer = new StandardAnalyzer();
        // 4.创建index目录对象,目录对象表示索引库的位置
        Directory directory = FSDirectory.open(Paths.get("src/main/resources/index"));
        // 5.创建IndexWriterConfig对象, 这个对象指定切分词使用的分词器
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
        // 6.创建IndexWriter输出流对象,指定输出位置和使用的config初始化对象。
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);
        // 7.修改文档
        indexWriter.deleteDocuments(new Term("id", "110161"));
        //indexWriter.deleteAll(); // 删除所有
        // 8.释放资源
        indexWriter.close();
    }
}

****************************************************************************************************************************************************************************

18、分词器
【1】搜索内容会用分词器再次切分。
【2】去掉停用词(的、是、a、an、the等)。大写转小写。
【3】分词器分为自带的和三方的分词器。
【4】比如:安徽合肥。默认分词器会分为 安 徽 合 肥。注意:分词时用的Analyzer,和搜索使用的一定要是同样的。

****************************************************************************************************************************************************************************

19、原生分词器
【1】StandardAnalyzer 对英文效果好。但是对中文就不行了,是按照字分词的。

****************************************************************************************************************************************************************************

20、空格分词器、SimpleAnalyzer
【1】根据空格分,这种对提前定义好支持的很好。仅仅去掉了空格。
【2】SimpleAnalyzer同样不支持中文分词。

****************************************************************************************************************************************************************************

23、第三方中文分词器
【1】使用中文分词器IKAnalyzer。扩展词典 指定的专有名字。停用词典 凡事出现在停用的都会被过滤掉。
 <!--三方分词器****************************************************************************************************************************************************-->
        <!-- https://mvnrepository.com/artifact/com.github.magese/ik-analyzer -->
        <dependency>
            <groupId>com.github.magese</groupId>
            <artifactId>ik-analyzer</artifactId>
            <version>8.1.0</version>
        </dependency>

IKAnalyzer.rar

****************************************************************************************************************************************************************************

24、高级查询(文本查询)
【1】文本搜索、范围搜索、组合搜索。
// 三、数据范围
    public static void rangeIndex() throws Exception {
        // 1.创建分词器(对搜索的内容进行分词使用)。如华为手机可能拆分为 华为 手机
        Analyzer analyzer = new IKAnalyzer();
        // 注意!!!:分词器要和创建索引的时候使用的分词器一模一样(不然搜索的时候就有问题)
        // 2.创建查询对象  // 第一个arg默认查询域   //
        Query query = IntPoint.newRangeQuery("price", 2500, 7999);
        // 4.设置Directory目录对象,指定索引库的位置
        Directory directory = FSDirectory.open(Paths.get("src/main/resources/index"));
        // 5.创建输入流对象
        IndexReader indexReader = DirectoryReader.open(directory);
        // 6.创建搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        // 7.搜索并返回结果
        TopDocs topDocs_10 = indexSearcher.search(query, 10);
        // 8.获取结果集
        ScoreDoc[] scoreDocArray = topDocs_10.scoreDocs;
        // 9.遍历结果集
        System.out.println("共查询到 " + scoreDocArray.length + " 条数据");
        if (scoreDocArray != null) {
            for (ScoreDoc temp : scoreDocArray) {
                // 获取查询到的文档唯一ID,这个ID是Lucene在创建文档的时候自动分配的。
                int docId = temp.doc;
                // 通过文档ID读取文档
                Document document = indexSearcher.doc(docId);
                System.out.println("******************************************************************************************************");
                System.out.println("id: " + document.get("id"));
                System.out.println("name: " + document.get("name"));
                System.out.println("price: " + document.get("price"));
            }
        }
        // 10. 关闭流
        indexReader.close();
    }
【2】组合查询
 // 四、组合查询
    public static void togetherIndex() throws Exception {
        // 1.创建分词器(对搜索的内容进行分词使用)。如华为手机可能拆分为 华为 手机
        Analyzer analyzer = new IKAnalyzer();
        // 注意!!!:分词器要和创建索引的时候使用的分词器一模一样(不然搜索的时候就有问题)
        // 2.创建查询对象  // 第一个arg默认查询域   //
        Query query_1 = IntPoint.newRangeQuery("price", 2500, 17999);
        QueryParser queryParser = new QueryParser("name", analyzer);
        // 3.设置搜索关键词 queryParser.parse("华为 AND 手机")
        Query query_2 = queryParser.parse("苹果 OR 手机"); // queryParser.parse("id:华为手机") 指定从id查,不指定就从默认的name域查
        BooleanQuery.Builder builderQuery = new BooleanQuery.Builder();
        builderQuery.add(query_1, BooleanClause.Occur.MUST); // MUST = and   SHOULD= or
        builderQuery.add(query_2, BooleanClause.Occur.MUST);
        // 4.设置Directory目录对象,指定索引库的位置
        Directory directory = FSDirectory.open(Paths.get("src/main/resources/index"));
        // 5.创建输入流对象
        IndexReader indexReader = DirectoryReader.open(directory);
        // 6.创建搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        // 7.搜索并返回结果
        TopDocs topDocs_10 = indexSearcher.search(builderQuery.build(), 10);
        // 8.获取结果集
        ScoreDoc[] scoreDocArray = topDocs_10.scoreDocs;
        // 9.遍历结果集
        System.out.println("共查询到 " + scoreDocArray.length + " 条数据");
        if (scoreDocArray != null) {
            for (ScoreDoc temp : scoreDocArray) {
                // 获取查询到的文档唯一ID,这个ID是Lucene在创建文档的时候自动分配的。
                int docId = temp.doc;
                // 通过文档ID读取文档
                Document document = indexSearcher.doc(docId);
                System.out.println("******************************************************************************************************");
                System.out.println("id: " + document.get("id"));
                System.out.println("name: " + document.get("name"));
                System.out.println("price: " + document.get("price"));
            }
        }
        // 10. 关闭流
        indexReader.close();
    }

****************************************************************************************************************************************************************************

26、实际案例
【1】商城页面。需求:商品名称,价格筛选等
【2】关闭springboot缓存spring.thymeleaf.cache=false
【3】不得不说thymeleaf真没有VUE好用,卧槽。

****************************************************************************************************************************************************************************

36、相关度排序
【1】词的权重。Term Frequency 出现的次数、 Document Frequency 出现的文档个数

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

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

相关文章

【软件开发规范篇】JAVA后端开发编程规范

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

Python数据分析案例43——Fama-French回归模型资产定价(三因子/五因子)

案例背景 最近看到要做三因子模型的同学还挺多的&#xff0c;就是所谓的Fama-French回归模型&#xff0c;也就是CAMP资本资产定价模型的升级版&#xff0c;然后后面还升级为了五因子模型。 看起来眼花缭乱&#xff0c;其实抛开金融资产定价的背景&#xff0c;从机器学习角度来…

04_jvm性能调优_并行收集器介绍

并行收集器&#xff08;此处也称为吞吐量收集器&#xff09;是类似于串行收集器的分代收集器。串行和并行收集器之间的主要区别在于并行收集器具有多个线程&#xff0c;用于加速垃圾回收过程。 通过命令行选项-XX:UseParallelGC 可启用并行收集器。默认情况下&#xff0c;使用…

消息队列与信号量(基本概念及操作接口介绍)

一、消息队列 基本概念 System V消息队列是Unix系统中一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;它允许进程互相发送和接收数据块&#xff08;消息&#xff09; 操作系统可以在内部申请一个消息队列&#xff0c;可以让不同的进程向消息队列中发送数据块&…

Linux Systemd基础教程

一、什么是systemd&#xff1f; systemd是Linux系统的一套基本构建模块。它提供了一个系统和服务管理器&#xff0c;作为PID 1运行并启动系统的其余部分。 systemd提供积极的并行化功能&#xff0c;使用套接字和D-Bus激活来启动服务&#xff0c;提供按需启动守护进程&#xf…

《自动机理论、语言和计算导论》阅读笔记:p352-P401

《自动机理论、语言和计算导论》学习第 12 天&#xff0c;p352-P401总结&#xff0c;总计 50 页。 一、技术总结 1.Turing Machine ™ 2.undecidability ​ a.Ld(the diagonalization language) 3.reduction p392, In general, if we have an algorithm to convert insta…

Git系列:config 配置

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

面试中算法(最大公约数)

高效求出两个整数的最大公约数&#xff0c;要尽量优化算法的性能。 def getDiv(a,b):mamax(a,b)mimin(a,b)#判断能被整除if ma%mi0:return mi#递归return getDiv(ma%mi,mi)if __name__ __main__:# print(getDiv(10, 25))print(getDiv(1000, 50))没错&#xff0c;这确实是辗转…

C++笔试强训day14

目录 1.乒乓球框 2.组队竞赛 3.删除相邻数字的最⼤分数 1.乒乓球框 链接 哈希表直接秒了&#xff1a; #include <iostream> #include <string> using namespace std; int main() {string s1, s2;while (cin >> s1 >> s2) { // 未知组数的输⼊int h…

新芯计划(1)时钟资源——MMCM与PLL

系列文章目录 1、同步设计——亚稳态 文章目录 系列文章目录前言一、时钟管理资源二、MMCM与PLLMMCM内部结构&#xff1a;PLL内部结构:区别 前言 本节围绕时钟资源展开&#xff0c;主要描述和比较MMCM和PLL&#xff0c;若内容有误&#xff0c;欢迎和感谢各位指正 参考视频&am…

IoTDB 入门教程 基础篇③——基于Linux系统快速安装启动和上手

文章目录 一、前文二、下载三、解压四、上传五、启动六、执行七、停止八、参考 一、前文 IoTDB入门教程——导读 二、下载 下载二进制可运行程序&#xff1a;https://dlcdn.apache.org/iotdb/1.3.1/apache-iotdb-1.3.1-all-bin.zip 历史版本下载&#xff1a;https://archive.…

Mysql中索引的概念

索引相关概念 基础概念&#xff1a; 在MySQL中&#xff0c;索引是一种数据结构&#xff0c;用于加快数据库查询的速度和性能。索引可以帮助MySQL快速定位和访问表中的特定数据&#xff0c;就像书籍的索引一样&#xff0c;通过存储指向数据行的指针&#xff0c;可以快速…

《老相册》读后感

外面在下着瓢泼大雨&#xff0c;豆粒大的雨点打在窗户上&#xff0c;发出啪啪的巨响。这样的雨天&#xff0c;是不适宜外出的&#xff0c;最惬意的方式就是一个人待在宿舍里&#xff0c;打开一本书&#xff0c;慢慢地看&#xff0c;静静地想&#xff0c;让所有的烦恼融化在这雨…

二叉树的迭代遍历 | LeetCode 144. 二叉树的前序遍历、LeetCode 94. 二叉树的中序遍历、LeetCode 145. 二叉树的后序遍历

二叉树的前序遍历&#xff08;迭代法&#xff09; 1、题目 题目链接&#xff1a;144. 二叉树的前序遍历 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3]示例 2&#x…

Docker Compose 部署若依前后端分离版

准备一台服务器 本次使用虚拟机&#xff0c;虚拟机系统 Ubuntu20.04&#xff0c;内存 4G&#xff0c;4核。 确保虚拟机能连接互联网。 Ubuntu20.04 安装 Docker 添加 Docker 的官方 GPG key&#xff1a; sudo apt-get update sudo apt-get install ca-certificates curl su…

1850H-The Third Letter

题目链接&#xff1a;The Third Letter 本道题目就是带权并查集的模板题&#xff0c;但又好久没学忘了&#xff0c;再复习一遍。。。 路径压缩函数模板&#xff1a; int root(int x){if(pre[x]!x){int troot(pre[x]);d[x]d[pre[x]];pre[x]t;}return pre[x]; } 之后就模拟一…

eNSP-浮动静态路由配置

ip route-static 192.168.1.0 24 192.168.3.2 preference 60 #设置路由 目标网络地址 和 下一跳地址 preference值越大 优先级越低 一、搭建拓扑结构 二、主机配置 pc1 pc2 三、配置路由器 1.AR1路由器配置 <Huawei>sys #进入系统视图 [Huawei]int g0/0/0 #进入接…

【DevOps】Jenkins 集成Docker

目录 1. 安装 Docker 和 Jenkins 2. 在 Jenkins 中安装 Docker 插件 3. 配置 Docker 连接 4. 创建 Jenkins Pipeline 5. 示例 Pipeline 脚本 6. 运行 Jenkins Job 7. 扩展功能 8、docker配置测试连接的时候报错处理 将 Docker 与 Jenkins 集成可以实现持续集成和持续交…

Java学习第05天-编程思维与编程能力

文章目录 综合应用案例&#xff1a;找素数数组元素的复制数字加密模拟双色球 综合应用 涉及的知识点&#xff1a; 变量、数组运算符&#xff1a;基本运算符、关系运算符、逻辑运算符流程控制&#xff1a;if、switch、for、while、死循环、循环嵌套跳转关键字&#xff1a;break、…

初识C语言——第十一天

操作符&#xff1a; 1. 算数操作符&#xff1a; - * / % 2. 移位操作符&#xff1a; >> &#xff08;右移&#xff09; << &#xff08;左移&#xff09; 移动的是二进制位 例如&#xff1a; int ba<<1; 3. 位操作符&#xff1a; & 按位与 | 按位…