【设计模式】访问者模式
访问者模式
访问者模式被称为是最复杂的设计模式,比较难理解并且使用频率不高。
在 GoF 的《设计模式》⼀书中,访问者者模式(Visitor Design Pattern)是这么定义的:
Allows for one or more operation to be applied to a set of objects at runtime, decoupling the operations from the object structure.
允许⼀个或者多个操作应⽤到⼀组对象上,解耦操作和对象本⾝。
访问者模式是一种将数据结构和数据操作分离的设计模式,属于行为型模式。
访问者模式的基本思想是: 假设系统中有一个由许多对象构成的对象结构(元素),这些对象的类都提供一个accept()
方法用来接受访问者对象的访问,不同的访问者访问同一对象可以产生不同的数据结果(访问者其实就是一个拥有visit()方法的接口) 。accept()
方法可以接收不同的访问者对象,然后在其内部将自己(元素)转发到访问者对象的visit()
方法内。
访问者模式的核心是解耦数据结构和数据操作,使得对元素的操作具备良好的扩展性。可以通过扩展不同的访问者来实现对同一元素集的不同操作。
如果你的系统中只是对单个对象(类)进行操作或者对多个类进行一种操作,那么就没必要使用访问者模式了。运用访问者模式是为了方便后续扩展操作类型,在对对象集(多个类对象)扩展操作的时候可以不需要修改所有类的代码。
当系统中存在类型数目稳定(固定)的一类数据结构时,可以通过访问者模式方便地实现对该类型所有数据结构的不同操作。
访问者模式类图
主要包含四个角色 :
Visitor 抽象访问者:接口或者抽象类,它定义了对每一个可访问元素(Visitable Element)访问的行为,它的参数就是可以访问的元素,它的方法个数理论上来讲与元素个数(Element的实现类个数)是一样的,从这点不难看出,访问者模式要求元素类的个数不能改变(不能改变的意思是说,如果元素类的个数经常改变,则说明不适合使用访问者模式)。
ConcreteVisitor:具体的访问者,实现对每一个元素的具体操作。
Element 抽象元素:元素接口,它定义了一个接受访问者(accept)的方法,其意义是指,每一个元素都要可以被访问者访问。
ConcreteElement:具体的元素类,它提供接受访问者的具体实现,而这个具体的实现,通常情况下是调用访问者提供的访问该元素类的方法。
代码示例
我们使用访问者模式模拟一个处理不同类型文件的场景
假设我们有三类文件,PDF,EXCEL,WORD,我们需要从三种文件中提取信息存到到自己的系统里(假设需要导入到自己的一个txt文件),然后还需要对三类文件都进行压缩等一系列功能
将不同文件类型定义为抽象元素(这是一个稳定的数据结构), 对文件的操作定义为访问者,代码如下 :
public abstract class ResourceFile {private String name;protected ResourceFile(String name) {this.name = name;}abstract void accept(Vistor vistor);}
public class PDFFile extends ResourceFile {protected PDFFile(String name) {super(name);}@Overridevoid accept(Vistor vistor) {vistor.visit(this);}
}public class ExcelFile extends ResourceFile{protected ExcelFile(String name) {super(name);}@Overridevoid accept(Vistor vistor) {vistor.visit(this);}
}public class WordFile extends ResourceFile{public WordFile(String name) {super(name);}@Overridevoid accept(Vistor vistor) {vistor.visit(this);}
}
public interface Vistor {void visit(PDFFile file);void visit(ExcelFile file);void visit(WordFile file);}
public class CompressionVistor implements Vistor{@Overridepublic void visit(PDFFile file) {System.out.println("压缩pdf文件");}@Overridepublic void visit(ExcelFile file) {System.out.println("压缩excel文件");}@Overridepublic void visit(WordFile file) {System.out.println("压缩word文件");}
}
public class ExtractVistor implements Vistor{@Overridepublic void visit(PDFFile file) {System.out.println("提取pdf文字内容");}@Overridepublic void visit(ExcelFile file) {System.out.println("提取excel文字内容");}@Overridepublic void visit(WordFile file) {System.out.println("提取word文字内容");}
}
public class Test {private static final List<ResourceFile> resourceFileList = new ArrayList<>();static {resourceFileList.add(new PDFFile("设计模式.pdf"));resourceFileList.add(new ExcelFile("Data.excel"));resourceFileList.add(new WordFile("笔记.doc"));}public static void main(String[] args) {for (ResourceFile resourceFile: resourceFileList) {resourceFile.accept(new CompressionVistor());}for (ResourceFile resourceFile: resourceFileList) {resourceFile.accept(new ExtractVistor());}}}
Double Dispatch
静态分派
静态分派(Static Dispatch)就是按照变量的静态类型(变量被声明时的类型)进行分派,从而确定方法的执行版本,静态分派在编译时就可以确定方法的版本,典型例子就是java的方法重载
java在静态分派的时候,我们可以根据多个判断依据(即参数个数和参数类型)判断使用哪个方法,所以java是静态多分派的语言
动态分派
动态分派,不是在编译期确定方法版本,而是在运行时才能确定
Single Dispatch,指的是我们仅仅需要根据对象运行时的类型来决定执行哪个对象的方法
Double Dispatch,指的是我们需要根据对象的运行时类型和参数的运行时类型来决定执行哪个对象的哪个方法 (二者区别主要在于是否可以根据方法参数运行时的类型来判断执行对象的哪个方法)
当前主流的⾯向对象编程语⾔(⽐如,Java、C++、C#)都只⽀持 Single Dispatch,不⽀持 Double Dispatch。
以Java为例,Java⽀持多态,代码可以在运⾏时获得对象的实际类型,然后根据实际类型决定调⽤哪个对象的方法。 Java 也⽀持方法重载,但 Java 设计的方法重载的语法规则是在编译时,根据传递进函数的参数的声明类型,来决定调⽤哪个重载方法。也就是说,具体执⾏哪个对象的哪个⽅法,只跟对象的运⾏时类型有关,跟参数的运⾏时类型⽆关。所以,Java 语⾔是 动态单分派的语言。
我们可以看下具体的例子 :
public class ParentClass {public void method() {System.out.println("ParentClass 执行method方法");}}public class SonClass extends ParentClass{@Overridepublic void method() {System.out.println("SonClass 执行method方法");}
}
public class SingleDispatch {public void method(ParentClass parentClass) {parentClass.method();}public void print(ParentClass parentClass) {System.out.println("打印parentClass");}public void print(SonClass sonClass) {System.out.println("打印sonClass");}
}
public class Test {public static void main(String[] args) {ParentClass s = new SonClass();SingleDispatch singleDispatch = new SingleDispatch();singleDispatch.method(s);//执⾏哪个对象的⽅法,由对象的实际类型决定(多态)singleDispatch.print(s);//执⾏对象的哪个⽅法,由参数对象的声明类型决定,这里声明的时ParentClass类型}}
动态双分派的语言不需要访问者模式
假设 Java 语⾔⽀持 动态双分派,那么下面的代码就可以编译通过,正常执行了。
public class ExtractExecutor {public void extract(PDFFile file) {System.out.println("提取pdf文字内容");}public void extract(WordFile file) {System.out.println("提取word文字内容");}public void extract(ExcelFile file) {System.out.println("提取excel文字内容");}}
public static void main(String[] args) {ExtractExecutor extractExecutor = new ExtractExecutor();for (ResourceFile resourceFile: resourceFileList) {//这里会编译报错: Cannot resolve method 'extract(ResourceFile)'extractExecutor.extract(resourceFile);}}
代码会在运⾏时,根据参数(resourceFile)的实际类型(PDFFile、ExcelFile、WordFile),来决定调用extract()
的三个重载方法中的哪⼀个,也就不需要访问者模式了。
访问者模式中的伪动态双分派
所谓的动态双分派就是在运行时根据对象和参数的运行时类型去判断调用哪个一个对象的哪个方法。访问者模式通过进行两次动态单分派来达到这个效果。
for (ResourceFile resourceFile: resourceFileList) {resourceFile.accept(new ExtractVistor());}
@Overridevoid accept(Vistor vistor) {vistor.visit(this);}
当调用accept()
方法的时候, 根据resourceFile的实际类型决定调用哪个文件的accept()
方法;
在执行accept()
方法的时候,根据vistor的示例类型来决定调用哪个Vistor的visist方法,此时的this的类型就是这个类的静态类型,这是在编译期就确定的,所以也可以确定是调用的哪个重载方法
通过工厂模式实现上述功能
上述的例子,如果对文件的操作也比较固定,也可以使用工厂模式来实现,定义⼀个包含 extract()
接⼝的Executor接⼝。PdfExtractExecutor、ExcelExtractExecutor、WordExtractExecutor 类实现 Executor接⼝,完成对各自⽂件的⽂本内容抽取。然后再提供一个ExtractExecutorFactory ⼯⼚类根据不同的⽂件类型,返回不同的 Executor。
public abstract class ResourceFile {private String name;protected ResourceFile(String name) {this.name = name;}abstract String getType();
}
public class PDFFile extends ResourceFile {protected PDFFile(String name) {super(name);}@OverrideString getType() {return "PDF";}}
public interface Executor {void extract(ResourceFile file);
}
//省略了WordExtractExecutor,ExcelExtractExecutor的代码
public class PDFExtractExecutor implements Executor{@Overridepublic void extract(ResourceFile file) {System.out.println("提取pdf的内容");}
}
public class ExtractExecutorFactory {private static Map<String, Executor> map = new HashMap<>();static {map.put("PDF", new PDFExtractExecutor());
// map.put("EXCEL", new ExeclExtractExecutor());
// map.put("WORD", new WordExtractExecutor());}public static Executor getExecutor(ResourceFile file) {return map.get(file.getType());}}
访问者模式在源码中的应用
Java 7 版本后,Files 类提供了 walkFileTree() 方法,该方法可以很容易的对目录下的所有文件进行遍历,需要 Path、FileVisitor 两个参数。其中,Path 是要遍历文件的路径,FileVisitor 则可以看成一个文件访问器。源码如下。
package java.nio.file;
public final class Files {...public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)throws IOException{return walkFileTree(start,EnumSet.noneOf(FileVisitOption.class),Integer.MAX_VALUE,visitor);}...
}
FileVisitor 提供了递归遍历文件树的支持,这个接口的方法表示了遍历过程中的关键过程,允许在文件被访问、目录将被访问、目录已被访问、发生错误等过程中进行控制。换句话说,这个接口在文件被访问前、访问中和访问后,以及产生错误的时候都有相应的钩子程序进行处理。
FileVisitor 主要提供了 4 个方法,且返回结果的都是 FileVisitResult 对象值,用于决定当前操作完成后接下来该如何处理。FileVisitResult 是一个枚举类,代表返回之后的一些后续操作。
package java.nio.file;import java.nio.file.attribute.BasicFileAttributes;
import java.io.IOException;
public interface FileVisitor<T> {FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)throws IOException;FileVisitResult visitFile(T file, BasicFileAttributes attrs)throws IOException;FileVisitResult visitFileFailed(T file, IOException exc)throws IOException;FileVisitResult postVisitDirectory(T dir, IOException exc)throws IOException;
}package java.nio.file;public enum FileVisitResult {CONTINUE,TERMINATE,SKIP_SUBTREE,SKIP_SIBLINGS;
}
FileVisitResult 主要包含 4 个常见的操作。
- FileVisitResult.CONTINUE:这个访问结果表示当前的遍历过程将会继续。
- FileVisitResult.SKIP_SIBLINGS:这个访问结果表示当前的遍历过程将会继续,但是要忽略当前文件/目录的兄弟节点。
- FileVisitResult.SKIP_SUBTREE:这个访问结果表示当前的遍历过程将会继续,但是要忽略当前目录下的所有节点。
- FileVisitResult.TERMINATE:这个访问结果表示当前的遍历过程将会停止。
通过访问者去遍历文件树会比较方便,比如查找文件夹内符合某个条件的文件或者某一天内所创建的文件,这个类中都提供了相对应的方法。它的实现也非常简单,代码如下
public class SimpleFileVisitor<T> implements FileVisitor<T> {protected SimpleFileVisitor() {}@Overridepublic FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)throws IOException{Objects.requireNonNull(dir);Objects.requireNonNull(attrs);return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult visitFile(T file, BasicFileAttributes attrs)throws IOException{Objects.requireNonNull(file);Objects.requireNonNull(attrs);return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult visitFileFailed(T file, IOException exc)throws IOException{Objects.requireNonNull(file);throw exc;}@Overridepublic FileVisitResult postVisitDirectory(T dir, IOException exc)throws IOException{Objects.requireNonNull(dir);if (exc != null)throw exc;return FileVisitResult.CONTINUE;}
}
一开始觉得这里的设计比较多余,后来仔细想了下,在不同场景下我们对文件树的遍历要求是不一样的,通过访问者模式,用户可以方便的定义自己的遍历操作
比方说在JavacPathFileManager里就重写了preVisitDirectory
和visitFile
方法
Files.walkFileTree(packageDir, opts, maxDepth,new SimpleFileVisitor<Path>() {@Overridepublic FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {Path name = dir.getFileName();if (name == null || SourceVersion.isIdentifier(name.toString())) // JSR 292?return FileVisitResult.CONTINUE;elsereturn FileVisitResult.SKIP_SUBTREE;}@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {if (attrs.isRegularFile() && kinds.contains(getKind(file.getFileName().toString()))) {JavaFileObject fe =PathFileObject.createDirectoryPathFileObject(JavacPathFileManager.this, file, pathDir);results.append(fe);}return FileVisitResult.CONTINUE;}});
总结
简单来说,访问者模式就是封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新操作。
访问者模式适用场景 :
- 数据结构稳定,但是作用于数据结构的操作经常变化
- 需要数据结构与数据操作分离
- 需要对不同数据类型(元素)进行操作,但是有不使用
if.. else ..
判断具体类型
优点:
- 使得数据结构和作用于结构上的操作解耦,使得操作集合可以独立变化。
- 扩展性好,添加新的操作或者说访问者会非常容易。
缺点:
- 增加新的元素类型会非常困难,每次新增元素类型,则访问者类必须增加对应元素类型的操作
- 违反了依赖倒置原则,访问者依赖的是具体元素类型,而不是抽象
- 变更元素的属性可能会导致对应的访问者类也需要修改
相关文章:
【设计模式】访问者模式
访问者模式 访问者模式被称为是最复杂的设计模式,比较难理解并且使用频率不高。 在 GoF 的《设计模式》⼀书中,访问者者模式(Visitor Design Pattern)是这么定义的: Allows for one or more operation to be applied to a set o…...
蓝桥杯刷题冲刺 | 倒计时27天
作者:指针不指南吗 专栏:蓝桥杯倒计时冲刺 🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾 文章目录1.递增序列2.等差素数列3.七段码4.亲戚5.连通块中点的数量1.递增序列 题目 链接:&am…...
RV1126_python人脸识别Retinaface+MobilefaceNet
RV1126_python人脸识别Retinaface+MobilefaceNet RV1126 具备RKNN 模块支持大部分如Pytorch、MXNet、Caffe、tensorflow、keras、onnx等常见框架,而且量化部署使用RKNN-toolkit非常方便。以下介绍通过RV1126实现的人脸识别过程。 首先人脸识别需要先做人脸检测>>人脸校正…...
HBase---HBase基础语法
HBase基础语法 文章目录HBase基础语法基本操作进入 HBase 客户端命令行查看命名空间查看命名空间下的表创建命名空间创建表查看表描述禁用/启用删除表新增列族删除列族更改列族存储版本的限制put 增加数据get 查看数据get条件查询删除指定列族下的指定列删除指定行全表扫描全表…...
2023年,PMP有多少含金量呢?
其实围绕以PMP含金量为中心的这个类似的小问题我好像也已经写了不少文章了。首先我肯定PMP的含金量,不管有多少质疑,这的确是事实。因为就是看中了他的价值考的,并且在项目的执行上收获了很多。 具体的可以看我接下来谈的PMP的价值&#x…...
vue动态路由
import Vue from vue import Router from vue-router import layout from ../components/layout Vue.use(Router) // 动态路由 export const asyncRouterMap = [ { path: /home, component: layout, name: home, meta: { title: 首页, icon: el-ic…...
被骗进一个很隐蔽的外包公司,入职一个月才发现,已经有了社保记录,简历污了,以后面试有影响吗?...
职场的套路防不胜防,一不留神就会掉坑,一位网友就被“骗”进了外包公司,他说公司非常隐蔽,入职一个月才发现是外包,但已经有了社保记录,简历污了,不知道对以后面试有影响吗?楼主说&a…...
华为OD机试 -租车骑绿岛(Java) | 机试题+算法思路+考点+代码解析 【2023】
租车骑绿岛 题目 部门组织绿岛骑行团建活动。租用公共双人自行车骑行,每辆自行车最多坐两人、做大载重M。 给出部门每个人的体重,请问最多需要租用多少双人自行车。 输入 第一行两个数字m、n,自行车限重m,代表部门总人数n。 第二行,n个数字,代表每个人的体重。体重都…...
【Java|基础篇】用思维导图理解逻辑控制
文章目录顺序结构分支结构if单分支语句if else双分支语句if else if else多分支语句switch语句循环语句for循环while循环do while循环continuebreak总结顺序结构 顺序结构是指代码按照从上往下的顺序依次执行 分支结构 选择语句是条件成立时,才会执行的语句.共有三种.分为是if…...
Go单元测试基础
Go单元测试基础1.go test工具2.单元测试函数3.go test -v/go test -run4.跳过某些测试用例5.子测试6.表格驱动测试7.并行测试8.使用工具生成测试代码9.测试覆盖率1.go test工具 Go语言中的测试依赖go test命令。编写测试代码和编写普通的Go代码过程是类似的,并不需…...
华为OD机试 -执行时长(Java) | 机试题+算法思路+考点+代码解析 【2023】
执行时长 题目 为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务,假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成 输入描述: 第一个…...
互联网检测服务器
互联网检测服务器 1. 题目要求2. 试题解析1. 题目要求 题目: 为了模拟 Internet 访问测试,请搭建网卡互联网检测服务。 2. 试题解析 根据windows的官方文档,互联网检测服务有专门的域名,通过注册表可以找到检测域名字符串的写法(字符串为www.msftconnecttest.com),具体位…...
YOLO系列模型改进指南
YOLO系列模型改进指南 目前包含yolov5,yolov7,yolov8模型的众多改进方案,效果因数据集和参数而定,仅供参考。 如果需要改进模型,建议baseline和改进模型也不要载入预训练权重,不然的话,他们的起…...
QML- 在QML定义JavaScript资源
在QML定义JavaScript资源一、概述二、后台代码实现文件三、共享JavaScript资源(库)一、概述 QML应用程序的一部分程序逻辑可以用 JavaScript 定义。JavaScript代码可以在QML文档中内联定义,也可以分离到单独的 JavaScript 文件中(在QML中称为JavaScript资源)。 QML…...
php(tp框架)使用七牛云对象存储
图片文件存服务器非常占用存储带宽资源,且用户访问体验也不佳,因此使用一些第三方oss存储就很有必要了。之前lz发布了一篇tp使用阿里云oss的博文。不过阿里oss是收费的。而七牛云提供了一些免费使用额度。所以,这里额外补充一篇。 1.前提准备…...
八大排序算法之插入排序+希尔排序
目录 一.前言(总体简介) 关于插入排序 关于希尔排序: 二.插入排序 函数首部: 算法思路: 算法分析 插入排序代码实现: 插入排序算法的优化前奏: 三.希尔排序(缩小增量排序) 1.算法思想: 2.算法拆分解析 序列分组 分组预排序: 分组预排序的另一种实现方式: 希尔…...
蓝桥杯第十四届蓝桥杯模拟赛第三期考场应对攻略(C/C++)
这里把我的想法和思路写出来,恳请批评指正! 目录 考前准备 试题1: 试题2: 试题3: 试题4: 试题5: 试题6: 试题7: 试题8: 试题9: 试题1…...
【数论】最大公约数、约数的个数与约数之和定理
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...
第28篇:Java日期Calendar类总结(二)
目录 1、获取系统当前时间 2、获取指定日期 3、对象字段类型 4 、对象信息设置 4.1 Set设置...
【Python】字符串 - 集大成篇
目录 1. 不同语言的字符串比较 1.1 C 语言 1.2 C 语言 1.2.1 C 风格字符串 1.2.2 C 风格字符串 1.3 JAVA 1.4 Python 2. Python 字符串 2.1 方法 2.2.1 title () 2.2.2 lower () 2.2.3 upper () 2.2.4 rstrip () 2.2.5 lstrip …...
IDEA: 如何导入项目模块 以及 将 Java程序打包 JAR 详细步骤
IDEA: 如何导入项目模块 以及 将 Java程序打包 JAR 详细步骤 、 文章目录IDEA: 如何导入项目模块 以及 将 Java程序打包 JAR 详细步骤IDEA 导入项目模块 Module一. 创建一个空项目二. 导入 Module三. 将 Module 与 当前项目关联上IDEA 将 Java程序打包成…...
算法的效率——时间复杂度和空间复杂度
文章目录1. 算法效率1.1 什么是算法1.2 算法的好坏2. 时间复杂度2.1 什么是时间复杂度2.2 时间复杂度的计算方法2.3 大O的渐进表示法2.4 常见时间复杂度计算举例3. 空间复杂度4. 常见复杂度对比1. 算法效率 1.1 什么是算法 目前普遍认可对算法的定义是:算法是解决…...
2021年 第12届 蓝桥杯 Java B组 省赛真题详解及小结【第1场省赛 2021.04.18】
总分:5 一、试题A:ASC 得分:5分 本题总分:5 分 【问题描述】 已知大写字母 A 的 ASCII 码为 65,请问大写字母 L 的 ASCII 码是多少? 【答案提交】 这是一道结果填空的题,你只需要算出结果后提…...
透过等待看数据库
等待分类与解决基本流程步骤1.定位问题系统等待往往能直观的反映出系统问题。通过一些常见的等待类型,同样可以找到系统瓶颈,结合性能计数器往往定位更准确。如:系统中存在大量IO类等待,那么可能表示你的磁盘或内存是语句运行缓慢…...
中科亿海微FPGA
国产FPGA中,紫光、安路、高云称得上是三小龙,其他的半斤八两,中科亿海微也算是其中之一。 其产品为亿海神针系列,如下: 可见其最小规模也有9.2KLUT,最大竟有136K之多了,对比其他国产࿰…...
【链表OJ题(三)】链表中倒数第k个结点
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯长路漫漫浩浩,万事皆有期待 文章目录链表OJ题(三)1. 链表…...
华为防火墙的学习
防火墙 - 含义和定义 什么是防火墙? 防火墙的工作原理 防火墙的区域: 包过滤防火墙----访问控制列表技术---三层技术 代理防火墙----中间人技术---应用层 状态防火墙---会话追踪技术---三层、四层 UTM---深度包检查技术----应用层 下一代防火墙 防火墙的…...
SPI 接口OLED 模块 - 兼容5V 和3.3V 电平
PCB 布局参考了老王0.8元128x32OLED显示屏转接板,开源项目地址:老王0.8元128x32OLED。 老王家买的屏幕放了快一年了,终于还是决定整个单独的模块,之前一直打算集成到开发板上的,不太灵活。相比那个转接板,主…...
css布局和定位
在Web开发中,CSS布局和定位是非常重要的技能。在这篇博客中,我们将深入探讨CSS布局和定位的概念、基本技术和最佳实践。 **CSS布局基础** ├── 盒模型 │ ├── 内边距 │ │ ├── padding │ │ ├── padding-top │ │ ├── p…...
python -- 批量读取多个文件,并将每个文件中相同变量累加
python – 批量读取多个文件,并将每个文件中相同变量累加 情况描述 现有多个nc文件,位于同一个文件夹中,如下所示每个文件中都有相同的变量,想要读取每个文件中的变量然后将其加起来意思就是说: 文件1中的变量文件2中…...
做移动网站优化首页软/外贸网站免费推广
官网说明:https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E8%AD%A6%E5%91%8A在linux下搭建nginx测试网页的时候,正常打开可以访问,当刷新后页面出现404 not found的问题说明:vue-router 默认 hash 模式 —— 使…...
专业型网站网站/厦门百度竞价开户
周期分析struct结构体redis代码。最后,越多越发现很多的代码其实大同小异。于struct有袋1,2不分析文件,关于set集合的一些东西,就放在下次分析好了,在选择下个分析的对象时,我考虑了一下,最后决定先把简单的…...
怎么免费推广自己的业务/seo营销推广全程实例
题目链接 首先考虑询问[1,n]怎么做 设 f[i][0/1]表示[1,i]以0/1结尾的不同子序列个数 则 \(if(A[i]) f[i][1] f[i-1][0] f[i-1][1] 1 , f[i][0] f[i-1][0]\)\(\ \ if(!A[i]) f[i][0] f[i-1][0] f[i-1][1] 1 , f[i][1] f[i-1][1]\) 很整齐,我们来写成矩阵的样…...
怎么做网站互换链接/广州百度关键词推广
前几天看了springside4的mini-web代码发现确实有不少新的东东,咱这次单说说Spring Data JPA吧。 引用springside4的 wiki关于对Spring Data JPA的简介 Spring Data JPA在JPA上又做了一层封装,只要编写接口就够了,不用写一行实现代码ÿ…...
好的wordpress主题/网店代运营公司靠谱吗
当我们使用类型number的input输入框的时候,我们可能需要限制输入的位数,这个时候通常会想到maxlength,但是maxlength是在number类型的时候是不支持的,下面是一些解决这种问题的方法。1)max和min max和min是number输入框…...
网站制作如何/福建seo搜索引擎优化
分析一下发现如果每一次放进去一个新,它就会对所有覆盖这个点的所有颜色的L加1那么另add(i,j)为第一个放到i第二个放到j放完之后这种状态有多少组交叉那么有 int add(int x, int y) {int cnt 0;for(int i0;i<26;i){if(pos[i][1] < x && pos2[i][1] &…...