深入学习系列--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编写,依赖于数组方法。

  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.
时间: 2024-10-05 02:46:09

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

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

Python学习系列(三)(字符串) 一个月没有更新博客了,最近工作上有点小忙,实在是没有坚持住,丢久又有感觉写的必要了,可见本人的坚持精神不佳,本系列没有任何目的,纯属业余学习,或者说是一时兴趣所致.通过本文,能够学习字符串的基本操作,日积月累,多多练习,学到了,会用了才是王道. 一.基本概念 1,关于转义问题 1)"''"方式: >>> s="Hello 'Jack'--" >>> print s Hello 'Jack'--

PHP学习系列(1)&mdash;&mdash;字符串处理函数(5)

31.ord() 函数返回字符串第一个字符的 ASCII 值. 语法:ord(string) 例子 <?php echo ord("h"); echo ord("hello"); ?> 输出: 104 104 32.parse_str() 函数把查询字符串解析到变量中. 语法:parse_str(string,array) array--可选.规定存储变量的数组名称.该参数指示变量存储到数组中. 说明:如果未设置 array 参数,由该函数设置的变量将覆

PHP学习系列(1)&mdash;&mdash;字符串处理函数(4)

16.hebrevc() 函数把希伯来文本从右至左的流转换为左至右的流.它也会把新行 (\n) 转换为 <br />.只有 224 至 251 之间的 ASCII 字符,以及标点符号受到影响. 语法:hebrev(string,maxcharline) maxcharline规定每行的最大字符数.如果可能,hebrev() 将避免把单词断开. 提示:hebrev() 和 hebrevc() 可以把希伯来逻辑文本转换为希伯来可见文本.希伯来可见文本不需要特殊的右至左字符支持,这使它对于在 web

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

6.chunk_split() 函数把字符串分割为一连串更小的部分.本函数不改变原始字符串. 语法:chunk_split(string,length,end) 参数: string——必需.规定要分割的字符串. length——可选.一个数字,定义字符串块的长度. end——可选.字符串值,定义在每个字符串块之后放置的内容. 例子 1 本例分隔每个字符,并添加 ".": <?php $str = "Hello world!"; echo chunk_spli

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

11.crc32() 函数计算一个字符串的 crc32 多项式.生成 string 参数的 32 位循环冗余校验码多项式.该函数可用于验证数据的完整性. 语法:crc32(string) 注意:由于 PHP 的整数是带符号的,许多 crc32 校验码将返回负整数,因此您需要使用 sprintf() 或 printf() 的 "%u" 格式符来获取表示无符号 crc32 校验码的字符串. 例子 1 在本例中,我们将在使用以及不使用 "%u" 格式符的情况下,输出 cr

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

一,模块的基本介绍 1,import引入其他标准模块 标准库:Python标准安装包里的模块. 引入模块的几种方式: i)引入模块:import   moduleName ii)引入模块下的函数:from moduleName import function1,function2,-- iii)引入模块下的所有函数:from moduleName import * 使用模块里的函数的方法: moduleName.function(agrs) 示例: >>> import math >

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

Python学习系列(四)(列表及其函数) Python学习系列(一)(基础入门) Python学习系列(二)(基础知识) Python学习系列(三)(字符串) 一.基本概念 1,列表是什么? 一种序列型数据类型,一有序数据集合用逗号间隔用方括号括起来. 2,几种访问形式 1)索引访问,语法结构:list_name[index].注意,列表的索引值从0开始.例如: 1 >>> li=[1,2,3,4,5] 2 >>> print li[2],li[0] 3 3 1 删除

黑 马 程 序 员_视频学习总结&lt;c语言&gt;----02 printf和scanf函数、基本语句和运算、流程控制、函数、数组、字符串

---------------------- ASP.Net+Unity开发..Net培训.期待与您交流! ---------------------- 一.printf函数 1.在使用peintf函数前必须加入#include <stdio.h>,使用它可以向标准输出设备(比如屏幕)输出数据,其中使用格式是 printf(“字符串”) :或者 printf(“字符串”, 格式符参数): 2.常用的格式符及其含义如图所示 3.格式符还可以添加输出宽度 二.scanf函数 1.在使用scanf函

ASP.NET MVC学习系列(二)-WebAPI请求

继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理. 这里我使用Jquery 来发起异步请求实现数据调用. 继续使用上一文章中的示例,添加一个index.html页面,添加对jquery的引用. 一.无参数Get请求 一般的get请求我们可以使用jquery提供的$.get() 或者$.ajax({type:"get"}) 来实现: 请求的后台Action方法仍为上篇文章中的GetU