字符串(String)
来源:互联网 发布:如何删除知乎提问 编辑:程序博客网 时间:2024/05/22 05:29
字符串(String)
1. 字符串的概念
1.1 字符串的定义
- 字符串,是一串文字和符号的序列,是由零个或多个字符的顺序排列所组成的数据结构,其基本组成元素是单个字符(char),字符串的长度可变。
- 字符串简称为串(String),是n(n≥0)个字符的一个有限序列。通常可记为S=”
a0a1a2……an−1 ”,其中,S是串名,可以是串变量名,也可以是串常量名。 - 用引号‘…’或“…”作为分界符括起来的叫做串值,其内的
ai 是串中的字符(0 ≤ i< n),n是串中的字符个数,也叫作串的长度,它不包括作为分界符的引号,也不包括串结束符‘\0’。
1.2 字符串的存储表示
- 字符串是一种特殊的线性结构,其存储表示有两种:数组存储表示和链接存储表示。
- 顺序串:字符串的数组存储表示简称为顺序串。
(1)它用一组地址连续的存储单元来存储字符串中的字符序列。
(2)可以使用定长的字符数组来实现。
(3)如果使用C语言中的类型定义,顺序串的存储分配可以分为两种:静态分配的数组表示和动态分配的数组表示。 - 链串:串的块链存储的组织形式与一般的单链表类似,主要区别在于,串中的一个存储结点可以存储多个字符。
(1)通常将链串中每个存储结点所存储的字符个数成为结点大小。
(2)当结点大小大于1时,串的最后一个结点的各个数据域不一定总能全部被字符占满,此时,应在这些未占用的数据域里不上不属于字符集的特殊字符(如“#”)以示区别。
(3)结点大小为1时存储密度低但操作方便,而结点大小大于1时存储密度高但操作不方便,具体如下图所示:
1.3 空串和空白串的区别
- 空串:长度为零的串叫做空串,除串结束符外,它不包含任何其他字符。
- 空白串:空白串的长度不为零,除串结束符外,它包含的其他字符均为空格。
2. 字符串的模式匹配
- 模式匹配(Pattern matching):查找模式串在目标串中的匹配位置的运算。
- 字符串的模式匹配问题描述:设有两个字符串T和pat,若打算在串T中查找是否有与串pat相等的子串,则称串T为目标(Target),称串pat为模式(Pattern)。
2.1 朴素的模式匹配——B-F算法(由Brute和Force提出,一种带回溯的字符串匹配算法)
- 基本想法:用串pat的字符依次与串T中的字符做比较。
- 算法原理如下:
(1)如果t0 =p0 ,t1 =p1 ……tm−1 =pm−1 ,则匹配成功,返回模式串pat第0个字符p0 在目标串T中匹配的位置。
(2)如果在其中某个位置i,ti ≠pi ,比较不等,这时将模式串pat右移一位,用pat中字符从头开始与T中字符依次比较,如此反复执行,直到得出结果:结果一,执行到某一趟,模式串的所有字符都与目标串对应字符相等,则匹配成功,结束算法;结果二,pat已经移到最后可能与T比较的位置,但不是每一个字符都能与T匹配,则匹配失败,结束算法。
2.2 模式匹配的改进算法——KMP算法(由D.E.Knuth、J.H.Morris和V.R.Pratt提出,一种无回溯的字符串匹配算法,更高效)
- 基本想法:引入一个跳转表next[],跳过不必要的比较过程,避免回溯,提高效率。
- 算法原理如下:
(1)用一个next特征函数来确定,当模式P中第j个字符与目标S中相应字符失配时,模式P中应当由哪个字符(设为第k+1个)与目标中刚失配的字符重新继续进行比较。
(2)设模式P=p0p1……pj−2pj−1 ,则它的next特征函数定义如下:
3. 字符串相关库函数
3.1 C++有关字符串的库函数
- C++提供的有关字符串的函数库的名字为
< string.h> ,其具体的字符串操作方法说明如下:http://blog.csdn.net/cainv89/article/details/47703949
3.2 STL有关字符串的类库
- STL提供的有关字符串的类库的名字为
< string> ,其具体的字符串操作方法说明如下:http://blog.csdn.net/cainv89/article/details/47208019
4. 字符串的实现
4.1 字符串的自定义类
文件:AString.h
#ifndef ASTRING_H_#define ASTRING_H_#include <iostream>#include <string.h>//#include <strstream>using namespace std;const int defaultSize = 128;class AString{public: AString(int sz = defaultSize); //构造函数,构造一个最大长度为sz,实际长度为0的字符串 AString(const char *init); //构造函数,构造一个最大长度为maxSize,由init初始化的新字符串对象 AString(const AString& obj); //拷贝构造函数,由一个已有的字符串对象ogj构造一个新字符串 ~AString(); //析构函数,释放动态分配的串空间并撤销改字符串对象public: int Length()const; //函数返回串*this的实际长度public: AString operator()(int pos, int len); //当0<=pos<maxSize且0<=len且pos+len<maxSize时,则在串*this中从pos所指出位置开始连续取len个字符组成子串返回public: int operator==(AString& obj)const; //判是否串相等,若串*this与obj相等,则函数返回1,否则函数返回0 int operator!=(AString& obj)const; //判是否串不相等,若串*this与obj不相等,则函数返回1,否则函数返回0public: int operator!()const; //判是否串空,若串*this为空,则函数返回1,否则函数返回0public: AString& operator=(AString& obj); //串obj赋值给当前串*thispublic: AString& operator+=(AString& obj); //若length(*this)+length(obj)<maxSize,则把串obj接在串*this后面public: char& operator[](int i); //取*this的第i个字符public: //若串pat与串*this中的某个子串匹配,则函数返回第1次匹配时子串在串*this中的位置,若串pat为空或在串*this中没有匹配子串,则函数返回-1 int Find(AString* pat)const; //B-F算法,朴素的模式匹配,带回溯的字符串匹配算法 int fastFind(AString* pat, int next[])const; //KMP算法,模式匹配的改进算法,无回溯的字符串匹配算法public: void getNext(int next[]); //计算next[]的算法private: char *ch; //串存放数组 int curLength; //串的实际长度 int maxSize; //存放数组的最大长度};#endif /*ASTRING_H_*/
4.2 字符串操作的实现
文件:AString.cpp
#include "AString.h"//构造函数,构造一个最大长度为sz,实际长度为0的字符串AString::AString(int sz){ if (sz >= 0) { maxSize = sz; curLength = 0; ch = new char[maxSize + 1]; ch[0] = '\0'; }}//构造函数,构造一个最大长度为maxSize,由data初始化的新字符串对象AString::AString(const char *init){ int len = strlen(init); maxSize = (len > defaultSize) ? len : defaultSize; curLength = len; ch = new char[maxSize + 1]; strcpy(ch, init);}//拷贝构造函数,由一个已有的字符串对象ogj构造一个新字符串AString::AString(const AString& obj){ maxSize = obj.maxSize; curLength = obj.curLength; ch = new char[maxSize + 1]; strcpy(ch, obj.ch);}//析构函数,释放动态分配的串空间并撤销改字符串对象AString::~AString(){ delete[] ch; ch = NULL;}//函数返回串*this的实际长度int AString::Length()const{ return curLength;}//当0<=pos<maxSize且0<=len且pos+len<maxSize时,则在串*this中从pos所指出位置开始连续取len个字符组成子串返回AString AString::operator()(int pos, int len){ AString temp; if ((pos >= 0) && (pos < maxSize) && (len >= 0) && ((pos + len) < maxSize)) { len = ((pos + len - 1) >= curLength) ? (curLength - pos) : len; temp.curLength = len; for (int i = 0, j = pos;i < len;i++, j++) { temp.ch[i] = ch[j]; } temp.ch[len] = '\0'; } return temp;}//判是否串相等,若串*this与obj相等,则函数返回1,否则函数返回0int AString::operator==(AString& obj)const{ return (strcmp(ch, obj.ch) == 0) ? 1 : 0;}//判是否串不相等,若串*this与obj不相等,则函数返回1,否则函数返回0int AString::operator!=(AString& obj)const{ return (strcmp(ch, obj.ch) != 0) ? 1 : 0;}//判是否串空,若串*this为空,则函数返回1,否则函数返回0int AString::operator!()const{ return (curLength == 0) ? 1 : 0;}//串obj赋值给当前串*thisAString& AString::operator=(AString& obj){ //两个串相等为自我赋值,否则字符串自身赋值出错 if (&obj != this) { delete[] ch; maxSize = obj.maxSize; curLength = obj.curLength; ch = new char[maxSize + 1]; strcpy(ch, obj.ch); } return *this;}//若length(*this)+length(obj)<maxSize,则把串obj接在串*this后面AString& AString::operator+=(AString& obj){ char *temp = ch; curLength += obj.curLength; maxSize = (maxSize >= curLength) ? maxSize : curLength; delete[] ch; ch = new char[maxSize+1]; strcpy(ch, temp); strcat(ch, obj.ch); delete[] temp; return *this;}//取*this的第i个字符char& AString::operator[](int i){ if ((i < 0) || (i >= curLength)) { exit(1); } return ch[i];}//若串pat与串*this中的某个子串匹配,则函数返回第1次匹配时子串在串*this中的位置,若串pat为空或在串*this中没有匹配子串,则函数返回-1//B-F算法,朴素的模式匹配,带回溯的字符串匹配算法int AString::Find(AString* pat)const{ int i = 0; int j = 0; for (i = 0;i <= curLength - pat->curLength;i++) { for (j = 0;j < pat->curLength;j++) { if (ch[i + j] != pat->ch[j]) { break; } } if (j == pat->curLength) { return i; } } return -1;}//KMP算法,模式匹配的改进算法,无回溯的字符串匹配算法int AString::fastFind(AString* pat, int next[])const{ int posP = 0; //模式串的扫描指针 int posT = 0; //目标串的扫描指针 int lengthP = pat->curLength; //模式串的长度 int lengthT = curLength; //目标串的长度 while ((posP < lengthP) && (posT < lengthT)) //对两串扫描 { if ((posP == -1) || (pat->ch[posP] == ch[posT])) //对应字符匹配 { posP++; posT++; } else { posP = next[posP]; } } if (posP < lengthP) { return -1; } else { return posT - lengthP; } return -1;}//计算next[]的算法void AString::getNext(int next[]){ int j = 0; int k = -1; next[0] = -1; while (j < curLength) { if ((k == -1) || (ch[j] == ch[k])) { j++; k++; next[j] = k; } else { k = next[k]; } }}
参考文献:
[1]《数据结构(用面向对象方法与C++语言描述)(第2版)》殷人昆——第四章
[2] 百度搜索关键字:字符串,KMP算法,跳转表
1 0
- 字符串string
- string字符串
- String字符串
- String字符串
- String字符串
- 字符串String
- 字符串String
- 字符串String
- String 字符串
- 字符串String
- String字符串
- 字符串string
- String字符串
- string字符串
- String字符串
- 字符串 String
- 字符串(String)
- String字符串
- UVC支持的摄像头列表
- Yoshua Bengio为什么能跟Hinton、LeCun相提并论?
- python 装饰器
- C语言练习题每练 1:字符串统计单词个数,单词由空格隔开
- 30 年后你拿什么养活自己(1):培养理财意识的一本书
- 字符串(String)
- 剖析C++对象模型
- 读取电话联系人
- Android的activity启动延迟加载
- 悬浮框效果
- DirectXMath
- File的sd卡
- 数据库三范式讲解
- NFS安装