数据结构之:字符串
来源:互联网 发布:windows svn 备份恢复 编辑:程序博客网 时间:2024/05/28 05:16
一、简介
字符串或者说串(String)是由数字、字母。下划线组成的一串字符。一般可以记为s="a0a1a2a3...an" (n>=0并且n是有限非负整数)。
从数据结构上来看,用c++来说,字符串是一种特殊的线性表,也就是里面的每个元素都是字符的一种线性表。可以是用数组实现,或者链表实现。具体的优缺点可以参照数组和链表的优缺点。
二、c++中的字符串string
而在c++中的string(头文件为string),其中保存的变量的char *,也就是一个不定长的字符数组,因为它重载了[]运算符,可以像数组一样去用下标访问元素;也可以说是一个链表,因为本质就是指针操作。但是其实内部实现是根据大小去调整string的大小的。我先贴出关于常用的一些string函数的声明:(没有考虑空间申请失败的情况)
#include <iostream>using namespace std;class String {private :char *s_data;int size;public ://构造函数和析构函数 String();String(const String &);String(const size_t, const char);~String();//一些属性函数 size_t length(); //返回长度 bool empty(); //是否为空 const char *c_str(); //返回指向开头的char指针//运算符重载friend String operator+ (const String &, const String &);friend String operator+ (const String &);friend String operator== (const String &, const String &);friend String operator!= (const String &, const String &);friend String operator< (const String &, const String &);friend String operator<= (const String &, const String &);friend String operator>= (const String &, const String &);friend String operator> (const String &, const String &);char &operator[] (const size_t);String &operator= (const String &);//一些串操作String substr(size_t, size_t); //返回两个size_t间的子串 String& append(const String&); //添加 String& insert(size_t, const String&); // 插入 String& assign(const String&, size_t, size_t); //替换 String& erase(size_t, size_t); //删除 };
其实实现也不是很难的,我觉得比较核心的是关于长度的变换这一部分,所以我只贴出构造函数和+号重载的实现:
String::String() {Length = 0;s_data = NULL;}String::String(const size_t length, const char c) {this -> Length = length;s_data = new char[length + 1]; //加一的目的是为了在最后添加一个结束标志\0 s_data[length] = '\0';strset(s_data, c); }String::String(const String& str) {Length = str.Length;s_data = new char[Length];strcpy(s_data, str.s_data);}String operator+(const String& s1, const String& s2) {String s;s.Length = s1.Length + s2.Length;s.s_data = new char[s.Length + 1];strcpy(s.s_data, s1.s_data);strcat(s.s_data, s2.s_data);return s;}
其中上面涉及的str开头的函数,是C标准库里面的<string.h>或者<cstring>里面的函数,是对char数组进行的一系列操作,所以string实际上是为了把char数组变成一种更加方便使用的一种对象,通过重载操作符,能做到像int,float这种数据类型的一些操作,同时又保留着char数组下标访问的特性,能直接用s[i]的形式去访问某一元素,而且也是在常数时间内就完成的。所以用完string,会有一种不再想用char*的感觉。
不过话说回来,如果对<string.h>里面的一些函数不了解的话,我建议先回去把这部分的学一学,如果需要的话,我可以把<string.h>的自己实现的一个头文件给你参考一下= =(你不嫌弃的话)。
三、字符串的模式匹配
模式匹配(Pattern matching)
-一个目标对象T(字符串)
-模式P(字符串)
在目标T中寻找一个给定的模式P的过程
例如:文本编辑时的特定词、句的查找;DNA信息的提取等等
简单来讲,就是给定你一大段字符串,然后查看里面是否存在某个子串,例如"abc"。
解决匹配问题的算法:朴素算法(Brute Force)和KMP算法(Knuth-Morrit-pratt)等等
*朴素算法
例如给定一个字符串 T="abcdabcdabcdef"
然后寻找在T中是否存在一个模式P=“abcdef"
所以朴素算法是指在T中一位一位得开始寻求匹配,例如第一步是:
abcdabcdabcdef
abcdef
这时候发现不匹配,然后就继续从T的第二位开始寻求匹配:
abcdabcdabcdef
abcdef
发现不匹配,就这样一直下去,一直到:
abcdabcdabcdef
abcdef
发现这时候匹配了模式P,所以存在,然后返回T中匹配的开头的下标。
这个就是朴素算法,像个大傻一样一个一个的挪,挪到合适的位置。分析一下,上面的例子肯定得嵌套两层的循环才能做到这样的遍历,所以时间复杂度肯定是在O(T * P)
假如这个字符串T很长很长,例如1W+个字符,而且模式P也有还几千个字符,那不就很麻烦?所以这就是朴素的局限性。下面会讲到KMP算法,这个就是一个比较简单的匹配的算法。
*KMP算法
-KMP是一种不回溯的匹配算法,也就是当T子串t不匹配模式P的是否,但是却存在模式P的子串p和t的子串t'匹配的话,假如能消除这个冗余的操作的话,就能大大加快速度。
-KMP算法就是确定这样的一个情况,确定应该右移多少位。
-而且KMP右移k位的k值仅仅依赖于模式P的本身,和T无关。
如下直接推荐一个写KMP算法的博客,写得很好!
传送门:KMP算法
以下是KMP算法代码,主要分为构造next数组,已经主体的循环框架:(没测试过的)
#include <iostream>#include <string>using namespace std;int KMPStrMatching(string T, string P, int *N, int start) {int j = 0;int i = start;int tLen = T.length();int pLen = P.length();if (tLen - start < pLen) {return -1;}while (j < pLen && i < tLen) {if (j == -1 || T[i] == P[j]) {i++;j++;} else {j = N[j];}}if (j >= pLen) {return (i - pLen);} else {return -1;}}int findNext(string P) {int j, k;int m = P.length();int *next = new int[m];next[0] = -1;j = 0;k = -1;while (j < m - 1) {while (k >= 0 && P[k] != P[j]) {k = next[k];}j++;k++;next[j] = k;}return next;}
- 数据结构之 字符串
- redis数据结构之字符串
- 数据结构之字符串
- 数据结构之字符串
- 数据结构之字符串ADT
- 数据结构之字符串
- 数据结构之字符串
- 数据结构之字符串
- 数据结构之回文字符串
- 数据结构算法之字符串
- python数据结构之字符串
- python数据结构之字符串
- 数据结构之:字符串
- 数据结构入门小结之字符串
- 数据结构示例之复制字符串
- 数据结构示例之字符串替换
- 数据结构示例之字符串比较
- 数据结构示例之分割字符串
- ubuntu 14.04 apt-get 方式安装oracle JDK
- 如何让浏览器的滚动条消失但是还能滚动
- 070 定积分 和、积极限的计算
- 排序算法学习(一)
- UVa11520
- 数据结构之:字符串
- 在 Flask 中使用 Celery
- 求10 个整数中最大值。
- HDU 4609 3-idiots(FFT+容斥)
- 端口映射的几种方式
- matplotlib(一)——pyplot使用简介
- 将三个数按从大到小输出。
- ubuntu ssh 安装
- 欢迎使用CSDN-markdown编辑器