深入学习系列--Data Structure--02字符串
字符串可以说是我们实际工作中使用最多的数据类型了,常见的字符串操作包括链接、取子串、格式化等。这部分内容总体来说比较容易理解,最难的部分要数字符串的模式匹配方法了,尤其是KMP算法,需要通过实践加以记忆。
串的定义:是由零个或者多个字符组成的有限序列,又叫字符串。串的比较是通过其编码的顺序进行的(对于ASCII码来说,其通过7个二进制表示一个字符,共可以表示128个字符),通常来说,对于给定的两个字符串s=a1a2…an,t=b1b2…bm来说,如果n<m且ai=bi(i=1,2…n),那么有s<t;如果存在某个k<=min(m,n),使得ai=bi(i=1,2…k-1),ak<bk,则s<t。接下来通过一个表格来了解串的常见操作(用C#自定义字符串类实现)。
操作 |
诠释 |
StrAssign(T, *chars) |
生成一个其值等于字符串常量chars的串T |
StrCopy(T,S) |
串S存在,由串S复制得到T |
ClearString(S) |
若S存在,将串清空 |
StringEmpty(S) |
若S存在,返回true,否则返回false |
StrLength(S) |
返回串S的元素个数,即串的长度 |
StrCompare(S,T) |
若S>T返回值>0,若相等返回0,若S<T的返回值<0 |
Concat(T,S1,S2) |
用T返回由S1和S2联结成的新串 |
SubString(Sub,S,pos,len) |
若串存在,1<=pos<=StrLength(S),且0<=lenStrLength(S)-pos+1, 用Sub返回串S的第pos个字符起长度为len的子串。 |
Index(S,T,pos) |
串S和T存在,T是非空串,1<=pos<=StrLength(S) 若主串S中存在和串T相同的子串,则返回它在主串S中第pos个字符之后第一次出现的位置,否则返回0。 |
Replace(S,T,V) |
串S,T,V存在,T是非空串,用V替换主串S中出现的所有与T相等的不重叠的子串 |
StrInsert(S,pos,T) |
串S和T存在,1<=pos<=StrLength(S)+1 在串S的第pos个字符前插入串T |
StrDelete(S,pos,len) |
串S存在,1<=pos<=StrLength(S)-len+1 从串S中删除第pos个字符起长度为len的子串 |
串的存储结构:通常来说,串都是使用顺序存储结构来实现的,链式的存储结构不太适合串。串的顺序存储是由一组地址连续的存储单元来存储串中的字符序列的,按照预定义的大小,为每个定义的串变量分配一个固定长度的存储区,一般用定长数组实现,用'\n'来表示一个串值得终结。
串的实现,如下所示,使用javascript编写,依赖于数组方法。
//////////////////////////////////////基础部分/////////////////////////////////////////////////////////// function MyString(strArray) {
//均需依赖于数组的操作
this.strArray = strArray;
this.strCopy = function() {
var newString = new MyString();
newString.strArray = this.strArray.slice();
return newString;
}
this.clearString = function() {
this.strArray = [];
} this.stringEmpty = function() {
if (this.strLength() == 0) {
return true;
}
return false;
}
this.strLength = function() {
return this.strArray.length;
} this.strCompare = function(otherStrArray) {
var compareLength = Math.min(this.strLength(), otherStrArray.length);
var i;
for (i = 0; i < compareLength; i++) {
if (this.strArray[i] != otherStrArray[i]) {
break;
}
} if (this.strArray[i] > otherStrArray[i]) {
return 1;
} else if (this.strArray[i] == otherStrArray[i]) {
return 0;
} else {
return -1;
}
} this.concat = function(otherStrArray) {
var newString = new MyString();
newString.strArray = this.strArray.concat(otherStrArray);
return newString;
}
this.subString = function(pos, len) {
if (pos >= 0 && len >= 0 && pos + len < this.strLength()) {
var newString = new MyString();
newString.strArray = this.strArray.slice(pos, pos + len);
return newString;
}
}
this.index = function(subStrArray, pos) {
if (pos < 0 || subStrArray.length > this.strLength() || pos >= this.strLength() - subStrArray.length) {
return -1;
}
for (var i = pos; i < this.strLength(); i++) {
var tempI = i;
for (j = 0; j < subStrArray.length; j++) {
if (subStrArray[j] != this.strArray[tempI]) {
break;
}
tempI++;
}
// console.log(tempI);
if (tempI == i + subStrArray.length) {
return i - pos;
}
// console.log(i);
}
return -1;
} this.replace = function(originalSubStrArray, targetSubStrArray) {
//需要依赖于index方法
var pos = this.index(originalSubStrArray, 0);
this.strDelete(pos, originalSubStrArray.length);
this.strInsert(pos, targetSubStrArray);
} this.strInsert = function(pos, subStrArray) {
if (pos >= 0 && pos <= this.strLength()) {
var partA = this.strArray.slice(0, pos);
var partB = this.strArray.splice(pos, this.strLength());
this.strArray = partA.concat(subStrArray, partB);
}
} this.strDelete = function(pos, len) {
if (pos >= 0 && len >= 0 && pos + len <= this.strLength()) {
var partA = this.strArray.slice(0, pos);
var partB = this.strArray.splice(pos + len, this.strLength());
this.strArray = partA.concat(partB);
}
}
}
} //////////////////////////////////////测试部分///////////////////////////////////////////////////////////
var strArray = ['x', 'i', 'o', 'n', 'g', 'e', 'r'];
var otherStrArray = ['x', 'i', 'o', 'n', 'g', 'e', 'r'];
var tempStrArray = ['n', 'g'];
var replaceStrArray = ['t', 't']; var str = new MyString(strArray);
console.log(str);
var newStr = str.strCopy();
console.log(newStr);
console.log(newStr == str);
console.log(newStr === str);
console.log(newStr.strCompare(otherStrArray)); newStr = str.concat(otherStrArray);
console.log(newStr);
// var strArray = 'xionger'.split('');
// console.log(strArray);
// console.log(strArray.length);
newStr = str.subString(2, 2);
console.log(newStr); // str.strDelete(4, 2);
// console.log(str);
// str.strInsert(7, tempStrArray);
// console.log(str);
var index = str.index(tempStrArray, 2);
console.log(index); // str.replace(tempStrArray, replaceStrArray);
// console.log(str);
KMP模式匹配算法:可以看到之前的朴素模式匹配算法的时间复杂度为O(n2),效率比较低下,因此更合适的方式是由Knuth,Morris,Pratt三位科学家研究的模式匹配算法,可以大大的减少重复遍历的情况。在之前的朴素模式匹配的算法中存在两个嵌套的循环,外部循环不存在回溯,但存在重复比较,内部循环存在回溯。因此,可以想到的优化点就是内外循环的变量值得设置。这部分用文字表述将非常的复杂且不容易理解,接下来通过代码让我们来熟悉这部分知识,也是本文最难的部分。
借用博文http://www.cnblogs.com/c-cloud/p/3224788.html的解释,非常准确,有空时可以继续深入学习。
参考资料:
- 程杰. 大话数据结构[M]. 北京:清华大学出版社, 2011.
- 严蔚敏, 吴伟民. 数据结构(C语言版)[M]. 北京:清华大学出版社, 2004.
深入学习系列--Data Structure--02字符串的更多相关文章
- Python学习系列(三)(字符串)
Python学习系列(三)(字符串) Python学习系列(一)(基础入门) Python学习系列(二)(基础知识) 一个月没有更新博客了,最近工作上有点小忙,实在是没有坚持住,丢久又有感觉写的必要了 ...
- PHP学习系列(1)——字符串处理函数(1)
从09年开始使用JAVA到现在差不多5年多了,然后由于即将要去的公司(研究僧终于要毕业了!)是使用PHP,Python作为后台开发语言的,所以要开始一段双P的学习旅程.用过PHP的都说这是很简单的一门 ...
- PHP学习系列(1)——字符串处理函数(4)
16.hebrevc() 函数把希伯来文本从右至左的流转换为左至右的流.它也会把新行 (\n) 转换为 <br />.只有 224 至 251 之间的 ASCII 字符,以及标点符号受到影 ...
- PHP学习系列(1)——字符串处理函数(3)
11.crc32() 函数计算一个字符串的 crc32 多项式.生成 string 参数的 32 位循环冗余校验码多项式.该函数可用于验证数据的完整性. 语法:crc32(string) 注意:由于 ...
- PHP学习系列(1)——字符串处理函数(5)
31.ord() 函数返回字符串第一个字符的 ASCII 值. 语法:ord(string) 例子 <?php echo ord("h"); echo ord("h ...
- PHP学习系列(1)——字符串处理函数(2)
6.chunk_split() 函数把字符串分割为一连串更小的部分.本函数不改变原始字符串. 语法:chunk_split(string,length,end) 参数: string——必需.规定要分 ...
- 高级数据结构学习笔记 / Data Structure(updating)
树状数组 查询操作:O(logn) 修改操作:O(logn) #define lowbit(x) (x & -x) int tr[N]; // 树状数组 // 添加c个大小为x的数值 vo ...
- Python学习系列(六)(模块)
Python学习系列(六)(模块) Python学习系列(五)(文件操作及其字典) 一,模块的基本介绍 1,import引入其他标准模块 标准库:Python标准安装包里的模块. 引入模块的几种方式: ...
- Python学习系列(四)(列表及其函数)
Python学习系列(四)(列表及其函数) Python学习系列(一)(基础入门) Python学习系列(二)(基础知识) Python学习系列(三)(字符串) 一.基本概念 1,列表是什么? ...
随机推荐
- JS事件冒泡
JavaSciprt事件中有两个很重要的特性:事件冒泡以及目标元素. 事件冒泡: 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发.这 一过程被 ...
- 使用MySql数据库, 浏览器接收返回数据报错SyntaxError: unterminated string literal
用php写了一个很简单的页面, 用来记录常用的oracle的关键字和各种函数, 以后用起来查一下方便, 原来是用java写了一个web项目, 但是用起来太麻烦, 真的不如php方便, 然后就把整理的内 ...
- 数据字典和动态性能视图<五>
数据字典和动态性能视图 介绍:数据字典是什么 数据字典是 oracle 数据库中最重要的组成部分,它提供了数据库的一些系统信息. 动态性能视图记载了例程启动后的相关信息. 数据字典 数据字典记录了 ...
- iOS静态库.a文件制作和导入使用
iOS静态库.a文件制作: 1.新建Cocoa Touch Static Library工程 新建工程 - 选择iOS-FrameWork&Libary,选择 Cocoa Touch Stat ...
- db2 怎么计算两个时间相差多少个月。如2015-10-10 和2014-1-12
SELECT timestampdiff (256, char(timestamp('2013-12-30 20:30:30') - timestamp('2001-09-26 15:24:23')) ...
- js常用功能汇总
var Utils = function() { this.Tools; this.ui; }; Utils = new Utils(); Utils.prototype.Tools = { year ...
- linux sudo命令
Sudo”是Unix/Linux平台上的一个非常有用的工具,它允许系统管理员分配给普通用户一些合理的“权利”,让他们执行一些只有超级用户或其他 特许用户才能完成的任务,比如:运行一些像mount,ha ...
- BST、B树、B+树、B*树
一. BST BST即二叉搜索树Binary Search Tree(又叫二叉排序树Binary Sort Tree).它有以下特点: 所有非叶子结点至多拥有两个儿子(Left和Right): 所有结 ...
- 【kd-tree】bzoj2850 巧克力王国
分四种情况讨论:a,b>=0 a,b<0 a>=0,b<0 a<0,b>=0 然后每次检验是否进入一个矩形框 或者 是否直接利用这个矩形框的答案 仅仅利用两个对角的 ...
- 5.2 Adapter
1 ArrayAdapter 只可以简单的显示一行文本 ArrayAdapter<String> adapter = new ArrayAdapter<String>( thi ...