串(string)(或字符串)是由零个或多个字符组成的有限序列。串中字符的数目称为串的长度。零个字符的串称为空串(null string),它的长度为零。

串中任意个连续的字符组成的子序列称为该串的子串。包含子串的串相应地称为主串。通常称字符在序列中的序号为该字符在串中的位置。子串在主串中的位置则以子串的第一个字符在主串中的位置来表示。

只有当两个串的长度相等,并且各个对应位置的字符都相等时才相等。

串有3种机内表示方法:
* 1.定长顺序存储表示
* 2.堆分配存储表示
* 3.串的块链存储表示

定长顺序存储表示:

类似于线性表的顺序存储结构,用一组地址连续的存储单元存储串值得字符序列。在串的定长顺序存储结构中,按照预定义的大小,为每个定义的串变量分配一个固定长度的存储区,则可用定长数组来描述。

以下标为0的数组分量存放串的实际长度:

结构图:

实现:

 function SString() {
this.MAXSTRLEN = 10;
} exports.SString = SString;
SString.prototype = {
constructor: SString,
// 返回由s1和s2连接而成的新串
concat: function (s2) {
var t = new SString();
// 未截断
if (this[0] + s2[0] <= this.MAXSTRLEN) {
copyStr2T(this);
copyStr2T(s2, this[0]);
t[0] = this[0] + s2[0]; // 截断
} else if (this[0] < this.MAXSTRLEN) {
copyStr2T(this);
copyStr2T(s2, this[0], this.MAXSTRLEN - this[0]);
t[0] = this.MAXSTRLEN; // 截断(仅取s1)
} else {
copyStr2T(this, 0, this.MAXSTRLEN);
t[0] = this[0] = this.MAXSTRLEN;
} return t; function copyStr2T(str, start, end) {
start = start || 0;
for (var i = 1, len = end || str[0]; i <= len; i++) {
t[start + i] = str[i];
}
}
},
substring: function (position, len) {
position = ~~position || 0;
len = ~~len || this[0];
if (position < 0 || position > this[0] - 1 || len < 0 || len > this[0] - position)
throw new Error('unexpected parameter'); var sub = new SString();
for (var i = 1; i <= len; i++) {
sub[i] = this[position + i - 1];
}
sub[0] = len; return sub;
},
toString: function () {
var str = '';
for (var i = 1; this[i]; i++) {
str += this[i];
}
return str;
},
// 返回子串sstring在主串中的第position个字符之后的位置
index: function (sstring, position) {
var i = position || 0;
var j = 1; while (i <= this[0] && j <= sstring[0]) {
if (this[i] === sstring[j]) {
i++;
j++;
} else {
i = i - j + 2;
j = 1;
}
} return j > sstring[0] ? i - sstring[0] : -1;
},
kmpIndex: function (sstring, position) {
var i = position || 0;
var j = 1;
var next = getNext(sstring); while (i <= this[0] && j <= sstring[0]) {
if (j === 0 || this[i] === sstring[j]) {
++i;
++j;
} else {
j = next[j];
}
} return j > sstring[0] ? i - sstring[0] : -1;
}
}; function getNext(sstring) {
var i = 1;
var next = {1: 0};
var j = 0; while (i < sstring[0]) {
if (j === 0 || sstring[i] === sstring[j]) {
if(sstring[++i] !== sstring[++j]){
next[i] = j;
} else {
next[i] = next[j];
}
// next[++i] = ++j;
} else {
j = next[j];
}
} return next;
} var a = new SString();
var b = new SString();
for (var i = 0; i < 4; i++) {
a[i + 1] = i + '';
b[i + 1] = i + '';
}
a[0] = b[0] = 4;
var t = a.concat(b);
console.log(t + ''); // var d = new SString();
var str = 'acabaabaabcacaabc';
for(i = 0; i < str.length; i++){
d[i + 1] = str[i];
}
d[0] = str.length; var c = new SString();
str = 'abaabc';
for(i = 0; i < str.length; i++){
c[i + 1] = str[i];
}
c[0] = str.length; console.log(d.index(c));
console.log(d.kmpIndex(c));

单元测试代码:

 describe('SString tests', function(){
var a = new SString();
var b = new SString(); it('should concat without break strings', function(){
for(var i = 0; i < 4; i++){
a[i + 1] = i + '';
b[i + 1] = i + '';
}
a[0] = b[0] = 4; var t = a.concat(b);
console.log(a);
console.log(b);
expect(t[0]).toBe(8);
expect(t + '').toBe('01230123');
}); it('should break strings of b', function(){
for(var i = 0; i < 7; i++){
b[i + 1] = i + '';
}
b[0] = 7; var t = a.concat(b);
console.log(a);
console.log(b);
expect(t[0]).toBe(10);
expect(t + '').toBe('0123012345');
}); it('should break strings of a', function(){
for(var i = 4; i < 10; i++){
a[i + 1] = i + '';
}
a[0] = 10; var t = a.concat(b);
console.log(a);
console.log(b);
expect(t[0]).toBe(10);
expect(t + '').toBe('0123456789');
}); it('should get substring', function(){
console.log(a);
var t = a.substring(1, 10);
expect(t + '').toBe('0123456789'); t = a.substring(3, 5);
expect(t + '').toBe('23456');
});
});

在顺序存储结构中,实现串操作的原操作为“字符串序列的复制”,操作时间复杂度基于复制的字符串序列的长度。
另一操作特点是,如果在操作中出现串值序列的长度超过MAXSTRLEN时,约定用截尾法处理,这种情况不仅在求连接串时可能发生,在串的其他操作中,如插入,置换等也可能发生,克服这个弊病唯有不限定串长的最大长度,即动态分配串值的存储空间。

javascript实现数据结构:串--定长顺序存储表示以及kmp算法实现的更多相关文章

  1. 串的模式匹配 BF算法和KMP算法

    设有主串s和子串t,子串t的定位就是要在主串中找到一个与子串t相等的子串.通常把主串s称为目标串,把子串t称为模式串,因此定位也称为模式匹配. 模式匹配成功是指在目标串s中找到一个模式串t: 不成功则 ...

  2. javascript实现数据结构: 串的块链存储表示

    和线性表的链式存储结构相类似,也可采用链式方式存储串值.由于串结构的特殊性--结构中的每个数据元素是一个字符,则用链表存储串值时,存在一个“结点大小”的问题,即每个结点可以存放一个字符,也可以存放多个 ...

  3. 大话数据结构(十二)java程序——KMP算法及改进的KMP算法实现

    1.朴素的模式匹配算法 朴素的模式匹配算法:就是对主串的每个字符作为子串开头,与要连接的字符串进行匹配.对主串做大循环,每个字符开头做T的长度的小循环,直到成功匹配或全部遍历完成为止. 又称BF算法 ...

  4. 串String(1):串的实现(定长顺序存储结构)

    前言 PS:本文相关头文件.预编译以及typedef如下,阅读一遍以便于下面的理解: #include <stdio.h> #include <stdlib.h> #inclu ...

  5. javascript实现数据结构与算法系列

    1.线性表(Linear list) 线性表--简单示例及线性表的顺序表示和实现 线性表--线性链表(链式存储结构) 线性表的静态单链表存储结构 循环链表与双向链表 功能完整的线性链表 线性链表的例子 ...

  6. 《数据结构》之串的模式匹配算法——KMP算法

    //串的模式匹配算法 //KMP算法,时间复杂度为O(n+m) #include <iostream> #include <string> #include <cstri ...

  7. 数据结构——串(KMP)

    空串:长度为0的串 空格串:由一个或多个空格组成的串 串常用的3种机内表示方法: 定长顺序存储表示: 用一组地址连续的存储单元存储串的字符序列,每一个串变量都有一个固定长度的存储区,可用定长数组来描述 ...

  8. sql 数据类型 论可变长度字符串与定长性能差异(my sql版)

    首先从字节上来说CHAR是定长,意思就是只要输入在我这个定长以下,不管是几个字符,它的实际占用空间都是CHAR定长的长度.而VARCHAR则相对来说会节省一点空间,比如:你VARCHAR的长度设为10 ...

  9. 串、串的模式匹配算法(子串查找)BF算法、KMP算法

    串的定长顺序存储#define MAXSTRLEN 255,//超出这个长度则超出部分被舍去,称为截断 串的模式匹配: 串的定义:0个或多个字符组成的有限序列S = 'a1a2a3…….an ' n ...

随机推荐

  1. STM32F4_TIM输入波形捕获(脉冲频率)

    Ⅰ.概述 本文在前面文章“STM32基本的计数原理”的基础上进行拓展,讲述关于“定时器输入捕获”的功能,和上一篇文章“定时器比较输出”区别还是挺大的.在引脚上刚好相反:一个输入.一个输出. 本文只使用 ...

  2. 第六节:宿主如何使用AppDomain

    前面已经讨论了宿主以及宿主加载CLR的方式.同时还讨论了宿主如何告诉CLR创建和卸载AppDomain.为了使这些讨论更加具体,下面将描述一些常见的宿主和AppDomain使用情形.特别地,我要解释不 ...

  3. python datetime date time详解

    之前一直被datetime,date,time弄的有点乱,可能是因为看文档每太看明白,找到了两篇文章供大家阅读都是转载的,其中有些名词这里解释一下: 世界协调时间(Universal Time Coo ...

  4. python time 模块详解

    Python中time模块详解 发表于2011年5月5日 12:58 a.m.    位于分类我爱Python 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括: ...

  5. 使用MSYS2编译64位gvim

    1. 下载安装MSYS2 在https://msys2.github.io/下载MSYS2,推荐下载x86-64版,此版本内置了MinGW32与MinGW64 安装后首先更新MSYS2系统,顺序执行下 ...

  6. Tornado服务器的学习

    Tornado就是我们在 FriendFeed 的 Web 服务器及其常用工具的开源版本.Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞 ...

  7. extension 的一个应用 - 优化图片的读取机制

    枚举和 extension 都是 swift 中非常好用的特性.这里我们就来讨论一个应用的例子,供大家参考. 我们在开发 app 的时候,都会用到各种图片资源,而我们读取图片资源时主要是通过UIIma ...

  8. 调整maven配置文件

    maven的配置文件位置:maven安装位置\conf\settings.xml. 这次调整maven的配置文件主要解决三个问题: 调整本地依赖库位置 设置代理 添加远程资源库镜像节点 调整本地依赖库 ...

  9. pb对Web Service的操作可使用两种方式实现

    从PB8.0/9.0开始,就已经提供Web Service Proxy功能,能够直接进行相关程序的编写. 但是,部分老项目使用PB6.5开发 研究后发现,其实PB6.5要操作Web Service也挺 ...

  10. Linux C 文件与目录3 文件读写

    文件读写 文件读写是指从文件中读出信息或将信息写入到文件中.Linux文件读取可使用read函数来实现的,文件写入可使用write函数来实现.在进行文件写入的操作时,只是在文件的缓冲区中操作,可能没有 ...