朴素匹配算法

//S 主串 T 模式串

//匹配失败,回溯
i = i - j + 1
j = 0 //匹配成功,返回位置
i - j function indexOf(S,T,pos = 0){
let i = pos
let j = 0; while(i <= S.length && j <= T.length){
if(S[i] == T[j]){
++i
++j
}else{
//回溯
i = i - j + 1
j = 0
}
} if(j >= T.length){
return i - j
} else {
return 0
}
}

KMP算法

字符串前后缀

字符关系

A  B    C   A    B    B
0 k-1 k j-k j-1 j

执行过程

//i指针不必回溯
//next[j]表示回溯位置 /*
规则1:没有公共前后缀的情况,匹配失败时j = 0去匹配
s: a b (c) d e f g
t: a b (d) t串中a与后边的bd串都不相等,在d匹配c失败时,可以知道t[a] = s[a], t[b] = s[b],t[a] != t[b],因此t[a] != s[b] 因为t[a] != t[b] != s[b],所以不用比较t[a]与s[b],只需要将a移动到匹配失败的位置即可 s: a b (c) d e f g
t: (a) b d 规则2:有公共前后缀的情况,匹配失败时j 根据当前字符串的前后缀相似度进行匹配 s: a b c a b a b c a
t: a b c a b x 因为t[a] != t[b] != s[b] != s[c],所以匹配失败时不必比较s[b],s[c] s: a b c a b a b c a
t: a b c a b x 因为t[0],t[1] = t[3],t[4],由于t[3],t[4] = s[3],s[4] = t[0],t[1],所以也s[3],s[4]也不用比较 在于s串比较时,都是通过判断t串中有无重复的元素,来决定与s串的某一位置进行比较 next[j] = {
0,当j = 1时,next[j] = 0
Max:{k | 1 < k < j, 且 p1 - pk-1 = pj-k+1 - pj - 1}
1,其他情况
} 现在的问题转移到当匹配失败时,如何计算出j的回溯位置 ? k值就是公共前后缀的长度,如果k = 1,那么就是k + 1 = 2 t = abcdex
n = next[j] j: 1 2 3 4 5 6
t: a b c d e x
n: 0 1 1 1 1 1 j = 1,j是a,没有前后缀,next[1] = 0
j = 2,j是ab,1 到 j - 1时,只有字符a,没有公共前后缀,next[2] = 1
j = 3,j是abc,1 到 j - 1,没有公共前后缀,next[3] = 1
j = 4,j是abcd,1 到 j - 1 没有公共前后缀,next[4] = 1
最后结果:next[j] = [0,1,1,1,1,1] 当匹配失败时,调用next[j],假设现在时j = 6匹配失败了,next[6] = 1, 那么我们应该回溯到j = 1 进行匹配,也就是t[1] = a 当有公共前后缀的情况
t = abcabx
n = next[j] j: 1 2 3 4 5 6
t: a b c a b x
n: 0 1 1 1 2 3 j = 1,next[1] = 0
j = 2,1 到 j - 1的字符是a,next[2] = 1
j = 3,1 到 j - 1的字符是ab,next[3] = 1
j = 4,1 到 j - 1的字符是abc,next[4] = 1
j = 5,1 到 j - 1的字符是abca, 公共前后缀是a,next[5] = 2
j = 6, 1 到 j - 1的字符是abcab,公共前后缀是ab,next[6] = 3 当匹配失败时,j = 6,next[6] = 3,那么j回溯3去比较 j: 1 2 3 4 5 6 7 8 9
t: a b a b a a a b a
n: 0 1 1 2 3 4 2 2 3 当j = 1, next[1] = 0
当j = 2, next[2] = 1
当j = 3, next[3] = 1
当j = 4, 公共前后缀a,next[4] = 2
当j = 5,公共前后缀ab,next[5] = 3
当j = 6,公共前后缀aba,next[6] = 4
当j = 7,公共前后缀a,next[a] = 2
当j = 8,公共前后缀a,next[a] = 2
当j = 9,公共前后缀ab,next[a] = 3 当j = 9匹配失败时,next(9) = 3,j应该回溯到第j = 3的位置进行比较 j: 1 2 3 4 5 6 7 8 9
t: a a a a a a a a b
n: 0 1 2 3 4 5 6 7 8 j = 1, next[1] = 0
j = 2, next[2] = 1
j = 3, next[3] = 2
j = 4, next[4] = 3
j = 5, next[5] = 4
j = 6, next[6] = 5
j = 7, next[7] = 6
j = 8, next[8] = 7
j = 9, next[9] = 8 */
function get_next(T,next = []){
let i = 0;
let j = -1;
//第一个字符就匹配失败的情况
next[0] = -1; while(i < T.length - 1){
//假设没有前后缀,设置初始值,第二次循环在验证是不是真的没有前后缀
if(j == -1 || T[i] == T[j]){
//给没有公共前后缀和前后缀一致的字符添加回退索引
++i
++j
next[i] = j
}
else {
//根据失败位置索引,找到应该回退的索引
j = next[j]
}
} return next
}
//进行修正
// s: aab
// t: aaa
//当a与b不匹配时,前面的a与后面的a是一样的没有必要在进行匹配
function get_nextval(T,nextval = []){
let i = 1;
nextval[1] = 0;
let j = 0; while(i < T.length - 1){
if(j == -1 || T[i] == T[j]){
++i
++j
if(T[i] != T[j]){
nextval[i] = j
} else {
//如果前后缀相同的情况
//跳过层层回溯,直接回溯到开始位置
nextval[i] = nextval[j]
}
} else { j = nextval[j]
}
}
} function kmp_search(S,T,pos = 0){
let i = pos;
let j = 0;
let next = get_next(T)
console.log(next) while( i < S.length && j < T.length){
if(j === -1 || S[i] === T[j]){
//j === -1 的时候将i向后移动的同时将j归0
i++
j++
} else {
j = next[j]
}
} if(j === T.length){
return i - j
}
else {
return -1
}
}
//kmp另一种实现
function prefix_table(pattern = [],prefix = [],n){
pattern[0] = 0
let len = 0
let i while( i < n){
if(pattern[i] == pattern[len]){
len ++
prefix[i] = len
i ++
}
else {
if(len > 0){
len = prefix[len - 1]
} else {
prefix[i] = len
i ++
}
}
}
} function move_prefix_table(prefix = [],n){
let i
for(i = n - 1; i > 0; i--){
prefix[i] = prefix[i - 1]
}
prefix[0] = -1
} function kmp_search(text = [],pattern = []){
let n = pattern.length
let m = text.length
let prefix = []
let i = 0
let j = 0 prefix_table(pattern,prefix,n)
move_prefix_table(prefix,n) while( i < m){
if( j == n - 1 && text[i] == pattenr[j]){
console.log(i - j)
j = prefix[j]
}
if(text[i] == pattern[j]){
i++
j++
}
else {
j = prefix[j]
if(j == -1){
i++
j++
}
}
}
}

js串结构的更多相关文章

  1. sdut 2125串结构练习--字符串匹配【两种KMP算法】

    串结构练习——字符串匹配 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目链接:http://acm.sdut.edu.cn/sduto ...

  2. (二)js选择结构

    1.js的执行顺序. a)    一般按照书写的顺序来执行. b)    另外一种是通过判断然后执行下一项语句. 注:一般讲js语句写在body内容的最后来执行. 2.js的结构 a)    顺序结构 ...

  3. [转]Vue.js 目录结构

    本文转自:http://www.runoob.com/vue2/vue-directory-structure.html 上一章节中我们使用了 npm 安装项目,我们在 IDE(Eclipse.Ato ...

  4. SuggestFrameWork js代码结构

    关于suggestFrameWork的使用教程网上很多,如果您仅仅想知道如何使用请移步.这里展现一下js代码实现结构 下载地址 http://sourceforge.net/projects/sugg ...

  5. (三)js循环结构

    1.循环结构 a)    当循环 语法:while(condition){         code...     }     do(){         code...     } while(); ...

  6. JS 选择结构语句与循环结构语句

    笔记整理自:廖雪峰老师的JS教程 选择结构 与Java使用一致. 需要注意的 JavaScript把null.undefined.0.NaN和空字符串''视为false,其他值一概视为true. 循环 ...

  7. js串讲整理

    js子级窗口向父级窗口传值 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...

  8. Js 循环结构

    循环结构: for while do….while for循环 for(变量初始化;条件表达式;变量更新){ //循环体 } 说明: 第一步:变量初始化 只执行一次 第二步:判断表达式是否成立 成立则 ...

  9. Angular2.js——主从结构

    学习这一篇的内容,还回到我们快速起步的应用上来. 主从结构,我们想要做一个英雄的列表,我们希望用户在列表中选中一个英雄,然后这个被选中的英雄出现在详情视图中.主视图是英雄列表,从视图则是被选中英雄的详 ...

随机推荐

  1. 不信任的 .exe 怎么办,用 Windows 沙盒啊!

    简评:维基百科,在计算机安全领域,沙盒(sandbox)是种安全机制,为执行中的程式提供的隔离环境.通常是作为一些来源不可信.具破坏力或无法判定程序意图的程序提供实验之用. 微软正在尝试解决人们对运行 ...

  2. Leetcode 88 合并两个有序数组 Python

    合并两个有序数组 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分 ...

  3. CSS02--四种样式、背景、文本、链接状态、表格样式

    接上面的“CSS01”,我们接着来说一下样式.很多人不知道的是一个HTML元素有四种样式,分别是浏览器默认样式.外部样式.内部样式.内联样式,而它们的优先级是越来越高的,后面的样式会覆盖前面的样式.多 ...

  4. jquery scrollTop()与scrollLeft()

    1.scrollLeft() scrollLeft() 方法设置或返回被选元素的水平滚动条位置. 提示:当滚动条位于最左侧时,位置是 0. 当用于返回位置时:该方法返回第一个匹配元素的滚动条的水平位置 ...

  5. ThreadLocal系列(一)-ThreadLocal的使用及原理解析

    ThreadLocal系列之ThreadLocal(源码基于java8) 项目中我们如果想要某个对象在程序运行中的任意位置获取到,就需要借助ThreadLocal来实现,这个对象称作线程的本地变量,下 ...

  6. 初识Flask框架,以及Flask中的模板语言jinjia2和Flask内置的Session

    一.web框架的对比 首先我们先来看下比较火的web框架 1.Django: 优点:大而全,所有组件都是组织内部开发高度定制化,教科书级别的框架 缺点:大到浪费资源,请求的时候需要的资源较高 2.Fl ...

  7. C++11 实现生产者消费者双缓冲

    基础的生产者消费者模型,生产者向公共缓存区写入数据,消费者从公共缓存区读取数据进行处理,两个线程访问公共资源,加锁实现数据的一致性. 通过加锁来实现 class Produce_1 { public: ...

  8. Java高并发之锁优化

    本文主要讲并行优化的几种方式, 其结构如下: 锁优化 减少锁的持有时间 例如避免给整个方法加锁 public synchronized void syncMethod(){ othercode1(); ...

  9. ftp&nginx搭建图片服务器

    下面使用ftp+nginx搭建一个简单的服务器 ftp用于文件的传输 nginx提供http服务 nginx服务器的安装和配置可以参照之前的教程:nginx安装及其配置详细教程 下面介绍ftp服务的安 ...

  10. 一次邮件发送协议SMTP问题排查

    项目中需要用到smtp协议来发送邮件告警,后端的技术栈主要是Java和C++,Java项目里直接在网上找的现成的类完美实现,163邮箱,腾讯邮箱和阿里邮箱均测试通过,不幸的是C++的项目也需要使用sm ...