字符串可以说是我们实际工作中使用最多的数据类型了,常见的字符串操作包括链接、取子串、格式化等。这部分内容总体来说比较容易理解,最难的部分要数字符串的模式匹配方法了,尤其是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编写,依赖于数组方法。

  1. //////////////////////////////////////基础部分///////////////////////////////////////////////////////////
  2.  
  3. function MyString(strArray) {
  4. //均需依赖于数组的操作
  5. this.strArray = strArray;
  6. this.strCopy = function() {
  7. var newString = new MyString();
  8. newString.strArray = this.strArray.slice();
  9. return newString;
  10. }
  11. this.clearString = function() {
  12. this.strArray = [];
  13. }
  14.  
  15. this.stringEmpty = function() {
  16. if (this.strLength() == 0) {
  17. return true;
  18. }
  19. return false;
  20. }
  21. this.strLength = function() {
  22. return this.strArray.length;
  23. }
  24.  
  25. this.strCompare = function(otherStrArray) {
  26. var compareLength = Math.min(this.strLength(), otherStrArray.length);
  27. var i;
  28. for (i = 0; i < compareLength; i++) {
  29. if (this.strArray[i] != otherStrArray[i]) {
  30. break;
  31. }
  32. }
  33.  
  34. if (this.strArray[i] > otherStrArray[i]) {
  35. return 1;
  36. } else if (this.strArray[i] == otherStrArray[i]) {
  37. return 0;
  38. } else {
  39. return -1;
  40. }
  41. }
  42.  
  43. this.concat = function(otherStrArray) {
  44. var newString = new MyString();
  45. newString.strArray = this.strArray.concat(otherStrArray);
  46. return newString;
  47. }
  48. this.subString = function(pos, len) {
  49. if (pos >= 0 && len >= 0 && pos + len < this.strLength()) {
  50. var newString = new MyString();
  51. newString.strArray = this.strArray.slice(pos, pos + len);
  52. return newString;
  53. }
  54. }
  55. this.index = function(subStrArray, pos) {
  56. if (pos < 0 || subStrArray.length > this.strLength() || pos >= this.strLength() - subStrArray.length) {
  57. return -1;
  58. }
  59. for (var i = pos; i < this.strLength(); i++) {
  60. var tempI = i;
  61. for (j = 0; j < subStrArray.length; j++) {
  62. if (subStrArray[j] != this.strArray[tempI]) {
  63. break;
  64. }
  65. tempI++;
  66. }
  67. // console.log(tempI);
  68. if (tempI == i + subStrArray.length) {
  69. return i - pos;
  70. }
  71. // console.log(i);
  72. }
  73. return -1;
  74. }
  75.  
  76. this.replace = function(originalSubStrArray, targetSubStrArray) {
  77. //需要依赖于index方法
  78. var pos = this.index(originalSubStrArray, 0);
  79. this.strDelete(pos, originalSubStrArray.length);
  80. this.strInsert(pos, targetSubStrArray);
  81. }
  82.  
  83. this.strInsert = function(pos, subStrArray) {
  84. if (pos >= 0 && pos <= this.strLength()) {
  85. var partA = this.strArray.slice(0, pos);
  86. var partB = this.strArray.splice(pos, this.strLength());
  87. this.strArray = partA.concat(subStrArray, partB);
  88. }
  89. }
  90.  
  91. this.strDelete = function(pos, len) {
  92. if (pos >= 0 && len >= 0 && pos + len <= this.strLength()) {
  93. var partA = this.strArray.slice(0, pos);
  94. var partB = this.strArray.splice(pos + len, this.strLength());
  95. this.strArray = partA.concat(partB);
  96. }
  97. }
  98. }
  99. }
  100.  
  101. //////////////////////////////////////测试部分///////////////////////////////////////////////////////////
  102. var strArray = ['x', 'i', 'o', 'n', 'g', 'e', 'r'];
  103. var otherStrArray = ['x', 'i', 'o', 'n', 'g', 'e', 'r'];
  104. var tempStrArray = ['n', 'g'];
  105. var replaceStrArray = ['t', 't'];
  106.  
  107. var str = new MyString(strArray);
  108. console.log(str);
  109. var newStr = str.strCopy();
  110. console.log(newStr);
  111. console.log(newStr == str);
  112. console.log(newStr === str);
  113. console.log(newStr.strCompare(otherStrArray));
  114.  
  115. newStr = str.concat(otherStrArray);
  116. console.log(newStr);
  117. // var strArray = 'xionger'.split('');
  118. // console.log(strArray);
  119. // console.log(strArray.length);
  120. newStr = str.subString(2, 2);
  121. console.log(newStr);
  122.  
  123. // str.strDelete(4, 2);
  124. // console.log(str);
  125. // str.strInsert(7, tempStrArray);
  126. // console.log(str);
  127. var index = str.index(tempStrArray, 2);
  128. console.log(index);
  129.  
  130. // str.replace(tempStrArray, replaceStrArray);
  131. // console.log(str);

KMP模式匹配算法:可以看到之前的朴素模式匹配算法的时间复杂度为O(n2),效率比较低下,因此更合适的方式是由Knuth,Morris,Pratt三位科学家研究的模式匹配算法,可以大大的减少重复遍历的情况。在之前的朴素模式匹配的算法中存在两个嵌套的循环,外部循环不存在回溯,但存在重复比较,内部循环存在回溯。因此,可以想到的优化点就是内外循环的变量值得设置。这部分用文字表述将非常的复杂且不容易理解,接下来通过代码让我们来熟悉这部分知识,也是本文最难的部分。

借用博文http://www.cnblogs.com/c-cloud/p/3224788.html的解释,非常准确,有空时可以继续深入学习。

参考资料:

  1. 程杰. 大话数据结构[M]. 北京:清华大学出版社, 2011.
  2. 严蔚敏, 吴伟民. 数据结构(C语言版)[M]. 北京:清华大学出版社, 2004.

深入学习系列--Data Structure--02字符串的更多相关文章

  1. Python学习系列(三)(字符串)

    Python学习系列(三)(字符串) Python学习系列(一)(基础入门) Python学习系列(二)(基础知识) 一个月没有更新博客了,最近工作上有点小忙,实在是没有坚持住,丢久又有感觉写的必要了 ...

  2. PHP学习系列(1)——字符串处理函数(1)

    从09年开始使用JAVA到现在差不多5年多了,然后由于即将要去的公司(研究僧终于要毕业了!)是使用PHP,Python作为后台开发语言的,所以要开始一段双P的学习旅程.用过PHP的都说这是很简单的一门 ...

  3. PHP学习系列(1)——字符串处理函数(4)

    16.hebrevc() 函数把希伯来文本从右至左的流转换为左至右的流.它也会把新行 (\n) 转换为 <br />.只有 224 至 251 之间的 ASCII 字符,以及标点符号受到影 ...

  4. PHP学习系列(1)——字符串处理函数(3)

    11.crc32() 函数计算一个字符串的 crc32 多项式.生成 string 参数的 32 位循环冗余校验码多项式.该函数可用于验证数据的完整性. 语法:crc32(string) 注意:由于 ...

  5. PHP学习系列(1)——字符串处理函数(5)

    31.ord() 函数返回字符串第一个字符的 ASCII 值. 语法:ord(string) 例子 <?php echo ord("h"); echo ord("h ...

  6. PHP学习系列(1)——字符串处理函数(2)

    6.chunk_split() 函数把字符串分割为一连串更小的部分.本函数不改变原始字符串. 语法:chunk_split(string,length,end) 参数: string——必需.规定要分 ...

  7. 高级数据结构学习笔记 / Data Structure(updating)

    树状数组   查询操作:O(logn) 修改操作:O(logn) #define lowbit(x) (x & -x) int tr[N]; // 树状数组 // 添加c个大小为x的数值 vo ...

  8. Python学习系列(六)(模块)

    Python学习系列(六)(模块) Python学习系列(五)(文件操作及其字典) 一,模块的基本介绍 1,import引入其他标准模块 标准库:Python标准安装包里的模块. 引入模块的几种方式: ...

  9. Python学习系列(四)(列表及其函数)

    Python学习系列(四)(列表及其函数) Python学习系列(一)(基础入门) Python学习系列(二)(基础知识) Python学习系列(三)(字符串) 一.基本概念 1,列表是什么?     ...

随机推荐

  1. canvas写的一个刮奖效果

    <!DOCTYPE html><head> <meta charset="utf-8"> <meta http-equiv="X ...

  2. 实战录 | Redis的主从服务器搭建

    <实战录>导语 云端卫士<实战录>栏目定期会向粉丝朋友们分享一些在开发运维中的经验和技巧,希望对于关注我们的朋友有所裨益.本期分享人为云端卫士安全平台工程师田全磊,将带来Red ...

  3. Intellij idea 设置svn 父目录文件显示状态颜色

    file-->setting-->version control

  4. jQuery中.attr()和.prop()的区别

    之前学习jQuery的时候,学习到了两种取得标签的属性值的方法:一种是elemJobj.attr(),另一种是elemJobj.prop().而在学习JS的时候,只有一种方法elemObj.getAt ...

  5. <雨季>

    忘不了节后漫长的雨季,灰暗阴冷的天气,潮湿的心情,总让我怀念家乡刺眼的阳光,即使在寒冷的冬季,唯有那窗外的紫荆花独自开放.飘落满地,给灰色的世界增添点色彩,合着同学们上早课的笑声,暂时排遣那一份思乡情 ...

  6. C++中类的前向声明的用法

    原创文章,未经博主允许禁止转载. C++的类可以进行前向声明.但是,仅仅进行前向声明而没有定义的类是不完整的,这样的类,只能用于定义指针.引用.以及用于函数形参的指针和引用.而不能定义对象(因为此时编 ...

  7. phpcms开启、关闭在线编辑模板的方法

    打开 caches/configs/system.php 文件 找到 'tpl_edit'=> 0,//是否允许在线编辑模板 修改此行代码中的数字为 1或0 即可

  8. iOS 开发中的CGFloat,CGPoint,CGSize和CGRect

    CGGeometry类定义几何元素的结构和操作集合元素的函数 1. 数据类型 CGFloat: 浮点值的基本类型 CGPoint: 表示一个二维坐标系中的点 CGSize: 表示一个矩形的宽度和高度 ...

  9. Mac中brew的安装

    brew是Mac OS的一个软件包管理工具,使用简单方便,就像ubuntu中的apt-get命令一样官方地址:http://brew.sh/index_zh-cn.html 终端下运行 /usr/bi ...

  10. [转] Linux中启动和停止jar包的运行

    脚本一: startTest.sh内容如下:#!/bin/shjava -jar Test.jar &       #注意:必须有&让其后台执行,否则没有pid生成echo $! &g ...