精华内容
下载资源
问答
  • 用列表1(set集合) 匹配 列表2内元素(有重复元素),然后将列表1内每个元素对应列表2的索引集合组合成字典,但我发现一但·行数达到几十万条时后,匹配效率太低,匹配次数为len(列表1)*len(列表2).,,请问下...
  • 基于模式匹配效率的光参量振荡器测定蓝光诱导的红外吸收
  • select 二级联动 之 匹配效率的提升

    常用的select控件的联动是每触发一次选中事件就根据选中的key带到后台进行一次匹配查询,而如果我们在页面初始化时就将所有要联动的数据取出保存下来(

    虽然可能在内存上占了一些比重,但是有时针对网络状况可以作权衡),有时情况也会好很多。举例如下:

     背景:现有若干家公司,每个公司下有若干部门小组,要求是选择公司更换时,二级select控件做出联动匹配变化。实现如下:
    首先,html:

     <div class="col-xs-4">
          <label class="margin-l-20 control-label label-title form-lable-required" for="User_Company">所属公司</label>
          <input type="hidden" id="hid_CompanyId" />
          <select class="form-control margin-l-10" id="User_Company" name="User_Company" data-size="10" data-msg="所属公司" οnchange="GetGroupByCompany()" style="width:59%;"></select>
     </div>
     <div class="col-xs-4">
          <label class="margin-l-20 control-label label-title form-lable-required" for="Data_Auth">所属小组</label>
          <input type="hidden" id="hid_GroupId" />
          <select class="form-control margin-l-10" id="User_Group" name="User_Group" data-size="10" data-msg="所属小组" style="width:59%;"></select>
     </div>

    浏览器解析效果如下:




    接着,页面初始化时,JS如下:


    var grouplist = '';//全局变量,保存公司-小组的二维数组
    
    //获取公司
        function GetCompanyInfo() {
            $.get("/SystemManage/GetListCompany", function (data) {
                returndata = eval('(' + data + ')');
                var options = '';
                $.each(returndata, function (i, o) {
                    if (o.Id == $("#hid_CompanyId").val()) {
                        options += '<option value=' + o.Id + ' selected>' + o.CompanyName + '</option>';
                    }
                    else {
                        options += '<option value=' + o.Id + '>' + o.CompanyName + '</option>';
                    }
                })
                $("#User_Company").append(options);
                GetGroupInitial();
            });
        }
    
        //获取所有小组
        function GetGroupByList() {
            $.get("/SystemManage/GetGroupList", {}, function (data) {
                var arr = new Array();
                for (var i = 0; i < eval(data).length; i++) {
                    arr[i] = new Array();
                    arr[i]["CompanyId"] = eval(data)[i].CompanyId;
                    arr[i]["Name"] = eval(data)[i].Name;
                }
                grouplist = arr;	//arr等同于二维数组
            })
        }
    最后,根据select 控件 的 οnchange="GetGroupByCompany()"  事件 自动匹配如下:
    //获取公司所有小组(点击事件自动匹配)
        function GetGroupByCompany() {
            var companyid= $("#User_Company").find("option:selected").val() ;
            $("#User_Group").empty();
                var options = '';
                for(var n=0;n<grouplist.length;n++) {
                    if (grouplist[n].CompanyId == companyid) {
                        options += '<option value=' + grouplist[n].CompanyId + '>' + grouplist[n].Name + '</option>';
                    }
                };
                $("#User_Group").append(options);
        }

    注:二级及以下下拉菜单在页面初始化时在这里是未被触发的,请自行初始化。

    以上。

    展开全文
  • 用例回归完成之后,一般都要生成一个summary_report.但是,发现生成报告的...下图中圈住的部分,没有注释掉的使用贪婪匹配,注释掉的使用非贪婪匹配 执行时间上二者差别巨大. 2.贪婪匹配时间 3.非贪婪匹配时间 ...

    用例回归完成之后,一般都要生成一个summary_report.但是,发现生成报告的时间耗时很久,搜集资料发现与匹配文件内容使用的正则表达式有很大关系.
    1.匹配模式说明
    下图中圈住的部分,没有注释掉的使用贪婪匹配,注释掉的使用非贪婪匹配
    执行时间上二者差别巨大;另外执行时间与正则表达式的长度也有关系,较长的表达式建议分段匹配.
    在这里插入图片描述
    2.贪婪匹配时间
    在这里插入图片描述
    3.非贪婪匹配时间
    在这里插入图片描述

    展开全文
  • 点击上方蓝色字体,关注我们之前一篇文章大致说了下最近正则优化的事,通过拆分超长正则让匹配效率提升近百倍,原文链接:用它匹配大数据长文本,让处理效率提升 100 倍 ~链接文章中对 AC 多模匹配的方式只是简单的...
    926bd9cbf9e60728a30a0e486a3e0283.gif

    点击上方蓝色字体,关注我们

    之前一篇文章大致说了下最近正则优化的事,通过拆分超长正则让匹配效率提升近百倍,原文链接:用它匹配大数据长文本,让处理效率提升 100 倍 ~

    链接文章中对 AC 多模匹配的方式只是简单的提了下,并没有做出详细的介绍,思路理清楚 但是 对于 AC自动机 还是有些模糊,只知道它的基础是 字典树KMP字符串匹配以后总不能一直把它当做黑盒去用吧,所以本文我们就看看 AC 自动机 到底是怎么回事,用它匹配长文本咋就这么快呢。

    Q:

    什么是 KMP 字符串匹配算法呢 

    A:

    KMP 字符串匹配算法的目的也是查找字符串,比如说 查找 'abc' 串中是否包含目标字符串 'ab',如果包含则返回包含的起始位置。

    KMP 算法会设置一个 next 指针,它的核心思想就是比过的字符串就不比了,而不是简单的暴力循环遍历查找。

    KMP 算法是单模式匹配,AC 自动机匹配是多模式匹配,可以说 AC 自动机匹配是  KMP 算法的升级,单模式匹配与多模式匹配的不同点在于单模式匹配是搜索一个关键字,多模式匹配是搜索多个关键字。

    它们的共同之处 都有个 next 指针AC 自动机 匹配效率高的原因除了它将字符做成字典树,由横向结构变为纵向之外,一个更重要的原因就是它的失败匹配机制,个人认为 AC 自动机匹配机制核心应该就是 匹配失败走失败指针匹配。

    AC 多模匹配算法大致可以分为 3 个部分:

    1. 构建字典树

    2. 设置失败指针 

    3.  多模匹配过程

    01  构建字典树

    字典树的构建过程是是这样的:

    当要往树中插入大量文本时,将文本按字符拆分计算,从前往后依次插入,当发现要插入的字符在其前一个字符的节点下没有节点与之相符,则需要创建新节点表示这个字符;如果发现其前节点下有与之相符的节点,则直接跳过,继续插入下一个节点。之后重复以上操作,直到遍历结束。

    01

    字典树包含的对象

    字典树的构建包括如下三个部分:

    • 字典树对象,包含一个个的树节点

    • 树节点对象,包含一个个的节点值对象

    • 节点值对象,包含了值的起始、终止下标以及实际存储的值

    以上三种对象有着明显的父子关系,树包含节点,节点包含值,构建出字典树,图示如下:

    f728a35c7d051c327b1e9ba9d22765ff.png

    02

    字典树构建参考代码

    1 字典树对象,字典树对象是对外暴露的对象,后续所有 AC 匹配的方法都在此对象中声明:

    • 添加模式串方法

    • 设置失败指针方法

    • 模式匹配方法

    public class ACTrie {    //是否建立了failure表    private Boolean failureStatesConstructed = false;    //根结点    private Node root;        public ACTrie() {        this.root = new Node(true);    }    /**     * 添加一个模式串     * @param keyword     */    public void addKeyword(String keyword) {}        /**     * 建立失败指针方法     */    private void constructFailureStates() {}        /**     * 模式匹配方法     *     * @param text 待匹配的文本     * @return 匹配到的模式串     */    public Collection parseText(String text) {}  }

    2 树节点对象,树节点对象的方法主要有:

    • 节点新增方法

    • 跳转到下一个节点方法

     private static class Node{        //构建字符与节点的关系        private Map map;        //节点中存入的所有数值        private List emits;        //失败指针指向的节点        private Node failure;        //判断此节点是否为根结点        private Boolean isRoot = false;        public Node(){            map = new HashMap<>();            emits = new ArrayList<>();        }        public Node(Boolean isRoot) {            this();            this.isRoot = isRoot;        }        //节点新增方法        public Node insert(Character character) {            Node node = this.map.get(character);            if (node == null) {                node = new Node();                map.put(character, node);            }            return node;        }        //记录所有添加的值 配合节点新增方法使用        public void addEmit(String keyword) {            emits.add(keyword);        }                public void addEmit(Collection keywords) {            emits.addAll(keywords);        }        /**         * success跳转         * @param character         * @return         */        public Node find(Character character) {            return map.get(character);        }        /**         * 跳转到下一个节点         * @param transition 接受字符         * @return 跳转结果         */        private Node nextState(Character transition) {            Node state = this.find(transition);            // 先按success跳转            if (state != null) {                return state;            }            //如果跳转到根结点还是失败,则返回根结点            if (this.isRoot) {                return this;            }            // 跳转失败的话,按failure跳转            return this.failure.nextState(transition);        }                public Collection children() {            return this.map.values();        }        //设置失败指针节点        public void setFailure(Node node) {            failure = node;        }        //获取失败节点        public Node getFailure() {            return failure;        }        //返回节点下所有记录键        public Set getTransitions() {            return map.keySet();        }        //返回节点下所有记录的值        public Collection emit() {            return this.emits == null ? Collections.emptyList() : this.emits;        }    }

    3 节点值对象

     public class Emit{   //匹配到的模式串   private final String keyword;   //匹配到的模式串起始下标   private final int start;    //匹配到的模式串终止下标   private final int end;    /**     * 构造一个模式串匹配结果     * @param start 起点     * @param end  终点     * @param keyword 模式串     */    public Emit(final int start, final int end, final String keyword) {        this.start = start;        this.end = end;        this.keyword = keyword;    }    /**     * 获取对应的模式串     * @return 模式串     */    public String getKeyword() {        return this.keyword;    }      }
    02   设置失败指针

    设置失败指针可以分为两步 :

    •   将深度为 1 的节点的失败指针直接指向父节点也就是根节点

      这一步比较简单,因为深度为 1 的节点如果查找失败,只能往上一层找,也就是往根节点找。

    •   为深度 > 1 的节点建立失败指针

    01

    深度大于1的节点失败指针的构建过程

    深度大于1的节点构造失败指针的过程概况如下:

    设一个节点的上的值为 c ,记为 start 节点 ,沿着它父节点的失败指针走,直到走到一个节点它的儿子节点中也有值为 c 的节点,将儿子节点记为 end 节点。然后把 start 节点的失败指针指向 end 节点即可。

    如果一直走到 root 节点都没有找到,那就把 start 节点的失败指针指向 root 节点。

    为了方便查看,我将上面链接文章的设置失败指针的图再拿下来,以深度3中的值为C的节点为例,走一下它的失败指针:

    e19b2b0e730c69a23fa5cddd3784932c.png

    记 深度3中的值为C 的节点 为 start,沿着它父节点(深度为2的值为b的节点)的失败指针走,找到深度为1的值为b的节点,发现它的儿子节点中也有值为C的节点,儿子节点记为 end 节点,此时将 start 节点的失败指针指向 end 节点即可。

    同理,深度3中的值为b的节点设置过程也是如此,沿着它父节点(深度为2的值为a的节点)的失败指针走,找到深度为1的值为a的节点,发现它的儿子节点中也有值为b的节点,儿子节点记为 end 节点,此时将 start 节点的失败指针指向 end 节点即可。

    d 节点由于一直找到根节点都没有匹配,所以它的失败指针指向了根节点。

    02

    设置失败指针参考代码

    设置失败指针的方法在树对象中,设置失败指针应该在匹配文章内容之前进行,参考代码如下:

    /** * 设置失败指针 */ private void constructFailureStates() {     Queue queue = new LinkedList<>();    // 第一步,将深度为1的节点的failure设为根节点    //特殊处理:第二层要特殊处理,将这层中的节点的失败路径直接指向父节点(也就是根节点)。    for (Node depthOneState : this.root.children()) {        depthOneState.setFailure(this.root);        queue.add(depthOneState);    }    this.failureStatesConstructed = true;    // 第二步,为深度 > 1 的节点建立failure表,这是一个bfs 广度优先遍历    /**     * 构造失败指针的过程概括起来就一句话:设这个节点上的字母为C,沿着他父亲的失败指针走,直到走到一个节点,他的儿子中也有字母为C的节点。     * 然后把当前节点的失败指针指向那个字母也为C的儿子。如果一直走到了root都没找到,那就把失败指针指向root。     * 使用广度优先搜索BFS,层次遍历节点来处理,每一个节点的失败路径。       */    while (!queue.isEmpty()) {        Node parentNode = queue.poll();        for (Character transition : parentNode.getTransitions()) {            Node childNode = parentNode.find(transition);            queue.add(childNode);            Node failNode = parentNode.getFailure().nextState(transition);            childNode.setFailure(failNode);            childNode.addEmit(failNode.emit());        }    } }
    03  多模匹配01

    AC 多模匹配过程

    AC自动机初始化完成并且设置好节点失败指针后,就可以使用 AC自动机 进行模式匹配了,模式匹配分为字符匹配和字符不匹配两种情况:

    • 当前字符匹配

    表示从当前节点沿着树边有一条路径可以到达目标字符,此时只需沿该路径走向下一个节点继续匹配即可,目标字符串指针移向下个字符继续匹配; 

    • 当前字符不匹配

    如果当前字符不匹配则去当前节点的失败指针所指向的节点继续匹配,匹配过程随着失败指针的指向走,一直走到失败指针指向根节点结束。

    使用自动机匹配模式串是,重复以上这 2 个过程中的任意一个,直到模式串走到结尾为止。

    02

    模式匹配参考代码

    /** * 模式匹配 * * @param text 待匹配的文本 * @return 匹配到的模式串 */public CollectionparseText(String text) {    //检查是否进行了失败指针设置过程    checkForConstructedFailureStates();    Node currentState = this.root;    //开始模式匹配    List collectedEmits = new ArrayList<>();    // 按字符拆分    for (int position = 0; position < text.length(); position++) {        Character character = text.charAt(position);        //通过字符查找下一个节点        currentState = currentState.nextState(character);                Collection emits = currentState.emit();        if (emits == null || emits.isEmpty()) {            continue;        }        for (String emit : emits) {            collectedEmits.add(new Emit(position - emit.length() + 1, position, emit));        }    }    return collectedEmits;}/** * 检查是否建立了失败指针 */private void checkForConstructedFailureStates() {    //树对象中会记录 失败指针是否设置 的标识,通过表示判断    if (!this.failureStatesConstructed) {        constructFailureStates();    }}

    至此,AC 自动机的匹配机制我们了解完了,它的重点还是在于失败指针的设置过程。

    了解了失败指针的设置与匹配的原理以后,现在再用是不是就感觉得心应手了呢,还不了解怎么实际使用的小伙伴,这里有个不错的入门案例,也是文章开始提到的 用它匹配大数据长文本,让处理效率提升 100 倍 ~  ,结合这篇文章再复盘一下,相信会对你有所帮助。

    PS: 关注公众号, 后台回复 "正则优化",可领取文中代码资料。

       THE END  用它匹配大数据长文本,让处理效率提升 100 倍 ~大数据存储- Hbase 整合 Hdoop、Hive这些 Hive 基础知识,你还记得吗大数据存储- Hbase 基础Phoenix - sql on hbaseHadoop 压缩实战聊聊那些从没听说过的并发的名词-管程搞懂微服务和大数据,从捕捉一头野猪说起

    671727f98bc889d5c9d249c73c202631.png  ? 

    点我写留言

    展开全文
  • Golang 正则匹配效率

    千次阅读 2019-07-04 10:15:37
    最近有个小需求,校验IMEI是否为15位纯数字(是否合法),以下是正则匹配,与自己实现的简单验证方式进行压测 package main import ( "regexp" "testing" ) func BenchmarkIsDigitalRegexp(b *testing.B) { for...

    最近有个小需求,校验IMEI是否为15位纯数字(是否合法),以下是正则匹配,与自己实现的简单验证方式进行压测

    package main
    
    import (
        "regexp"
        "testing"
    )
    
    func BenchmarkIsDigitalRegexp(b *testing.B) {
        for i := 0; i < b.N; i++ {
            _ = isDigitalRegexp("358901806972417")
        }
    }
    
    func BenchmarkIsDigital(b *testing.B) {
        for i := 0; i < b.N; i++ {
            _ = isDigital("358901806972417")
        }
    }
    
    func isDigitalRegexp(imei string) bool {
        if ok, _ := regexp.Match("^[0-9]{15}$", []byte(imei)); ok {
            return true
        }else {
            return false
        }
    }
    
    func isDigital(imei string) bool {
        n := len(imei)
        if n == 15 {
            for i := 0; i < n; i++ {
                if imei[i] >= 48 && imei[i] <= 57 {
                    continue
                }else {
                    return false
                }
            }
        }else {
            return false
        }
        return true
    }
    

    压测结果:

    C:\Users\M709FJSA\go\src\pprof_demo\re>go test -bench=. -benchmem
    goos: windows
    goarch: amd64
    pkg: pprof_demo/re
    BenchmarkIsDigitalRegexp-12       300000              4644 ns/op            6450 B/op         70 allocs/op
    BenchmarkIsDigital-12           200000000                9.48 ns/op            0 B/op          0 allocs/op
    PASS
    ok      pprof_demo/re   4.577s
    
    

    很明显,正则需要重新分配内存较多,从pprof生成图也可以看出,正则调用关系错综复杂

    在这里插入图片描述

    展开全文
  • 提升人货匹配效率》 1、千人千面机制下的标签完善 如何让我们的商品或者店铺获取到精准的流量,那还是回归到了人货匹配问题。 在千人千面的匹配原则下,系统一方面会给商家的商品或店铺打标签,另一方面,用户也...
  • 当我们在Python中使用正则表达式时,re...那么如果一个正则表达式要重复使用几千次,出于效率的考虑,我们应该先把这个正则先预编译好,接下来重复使用时就不再需要编译这个步骤了,直接匹配,提高我们的效率 ...
  • 一般来说,贪婪与非贪婪模式,如果量词修饰的子表达式相同,比如“.*”和“.*?”,它们的应用场景通常是不同的,所以效率上一般不具有可比性。...”,贪婪模式的匹配效率通常要高些。 同时还有一个事...
  • 现有一个pointmaps 的类型是LIst<Map<String,String>> 是时间点 , pointmaps 中每个map都有一个pdate(日期)的key 和若干个periodID(时间点id) 的key。...[b]怎么提高它的运行效率[/b]
  • 后仿真时会使用sdf文件确认时序信息反标到设计当中,仿真时sdf信息没有反标上,分析之后是因为有sdf文件的参数设置有问题,需要手动替换.需要替换的参数并不多,但是sdf文件比较大,有600M左右,打开...匹配的数据中有
  • 之前一篇文章大致说了下最近正则优化的事,通过拆分超长正则让匹配效率提升近百倍,原文链接:用它匹配大数据长文本,让处理效率提升 100 倍 ~链接文章中对 AC 多模匹配的方式只是简单的提了下,并没有做出详细的...
  • 以下哪项更有效,更好用?value.replaceAll("['‘’`]","")value.replaceAll("['‘’`]+","")我的猜测是,对于没有被替换的字符串的字符串,或者至少没有它们的序列,两者是相同的,或者第一个更好是不那么复杂....
  • 五周二次课(11月14日) 11.1 常用正则表达式 11.2 re正则对象和正则匹配效率比较 11.3 编译正则对象
  • 在项目中,我们经常会使用到for循环去匹配对应的数量,例如在成绩表里,我们只保存了学生的id,我们需要根据学生id去匹配对应的学生信息, 这里我就不谈为什么不join关联表去查询(毕竟数量多了,关联查询也是很慢...
  • 我们在较大数据库下,查询多条 模糊关键字的时候,like ‘condition1%’ or like ‘condition2%’ 效率太低。     此时可以用 [sql] view plaincopy SELECT * FROM USERTEST ...
  • i++) { //当当前两个索引所指的元素不同时,i保持不变,对j进行回溯,提高了查询效率 //此步骤为kmp算法核心 while (j > 0 && str1.charAt(i) != str2.charAt(j)){ j = next[j - 1]; } //当当前索引所指的两个字符...
  • (1) 蛮力匹配:  把n中每个单词与m中的每个单词一一比较。时间复杂度为:O(m*n)。估计谁也不会选这种。 (2) 二分查找:要求,对paper建有序索引。  paper排序的时间复杂度最好为O(m*logm)。  对letter...
  • 正则匹配是,优先编译成正则对象,然后再进行匹配,这样程序的效率更高   编译正则对象  正则匹配总写一个r是什么意思?  r表示raw的简及raw string 意思是原生字符,也就是说是这个字符串中间的特殊字符...
  • 最近在实际生产中由于数据量骤升,现有数据量提高了大约 3-4 倍,原本使用正则处理已经到了瓶颈,这次又有增量对生产来说可谓雪上加霜,而且随着正则词越加越多,匹配效率也越来越差,数据量的激增再加上正则词越加...
  • 在C#中使用正则表达式进行匹配指定的字符串,因为正则表达式的灵活多样,正则表达式的复杂程序会影响程序的匹配效率吗?
  • 以其简短的表现形式和高效的查找匹配效率总是让人爱不释手。本文旨在帮助大家入门正则并学会解决常见的正则问题,希望能帮到大家。一. 初识正则1. 正则给人的直观印象很多人觉得正则表达式很难,一般有两种情况:第...
  • 露天矿挖掘机和与之匹配的汽车数量,直接影响采装挖掘机和汽车作业效率,进而影响露天煤矿生产成本。通过分析确定随车铲比的增大,挖掘机成本逐步降低,汽车成本逐步增大,而总成本表现出先降低后增大的趋势。同时随车铲...
  • 业务办理的时候发现正则的匹配效率极其低下,耗时居然要1分钟,而jdk的String的index这个类居然耗时只有100分之一,至于具体的区别如下 具体的代码逻辑如下: 1、正则匹配耗时监控 //10、资讯主表、快讯表当...
  • 本文分析了纯相位匹配滤波实现特征识别的物理原因。据此我们修改了待识别物体的傅里叶变换的振幅,以减小光强度的动态范围。...用重铬酸盐明胶记录反射式全息匹配滤波器,从而获得高效率的相关检测。
  • KMP匹配算法-效率测试

    千次阅读 2016-11-07 13:56:48
    KMP匹配有关联的字符串效率比较高。 KMP匹配无关数据,效率也许比简单匹配低。 无关数据匹配//无关数据匹配 //模式匹配字符串P A B C D A B D A B A C D -1 0 0 0 -1 0 2 -1 0 2 1 0 //文本串S E H
  • 相关匹配的计算效率

    2018-08-29 10:55:02
    在频域下计算图像 I 与子模式 w 的相关响应,并提示最大的响应位置

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,505
精华内容 3,402
关键字:

匹配效率