字符串处理
来源:互联网 发布:淘宝大众评审 编辑:程序博客网 时间:2024/06/05 16:53
一、串的5种基本操作
1.串赋值(=)
2.串比较(!= ==)
3.求串长(length())
4.串连接(+)
5.求子串(substr())
串操作的本质是字符类型数组的复制,C++中的string类可以提供方便快捷的串操作。
二、其他操作
1.插入(insert())
已知插入点,可通过对串插入点前后分别取子串操作,再通过串连接操作实现。
2.删除(erase())
已知删除部分,可通过对串的删除部分前后分别取子串操作,再通过串连接操作实现。
3.替换(replace())
已知替换部分,可通过删除操作+插入操作实现。
三、模式匹配
1.简单的模式匹配算法
//在串str1中从k位置开始匹配str2,匹配成功返回首字母地址,匹配失败返回-1。//a为str1的长度,b为str2的长度int i,j;for(i=k;i<a-b;i++){ for(j=0;j<b;j++){ if(str1[i+j]!=str2[j]){ break; } } if(j==b){ return i; }}return -1;
2.KMP算法
(1)计算next(j)的算法:
//j的作用是遍历模式串//lengthP是模式串的长度int j=0,k=-1,lengthP=curLength;//next[i]表示在前i个字符中,前后串匹配的长度。//在该算法中,可理解成已匹配部分的后面一个字符的下标。//后面一个字符的下标刚好为前面已匹配部分的长度。next[0]=-1;while(j<lengthP){//如果后一个字符匹配,则i和k均往后移,判断下一个字符是否匹配 if(k==-1 || ch[j]==ch[k]){ j++;k++; next[j]=k; } else{//如果后面一个字符不匹配,则i不变,k变为前k个字符中已匹配部分的下一个字符的下标。//即next[k]//比较该字符和后面一个字符是否匹配,重复操作,直到匹配或-1结束。 k=next[k]; }}
该算法理解不易用语言表示,请参看https://www.bilibili.com/video/av3246487/?from=search&seid=17173603269940723925。
该算法重点理解next[i]存放的是前i个字符中,前后匹配部分的后一个字符的下标,也可以理解为前i个字符中匹配部分长度。
运用的思想是,较长的字符串由于最后一个字符不匹配,那么就从该字符串中找到最长的已匹配的字符串,判断字符串的后一个字符与当前字符是否匹配。
(2)主算法:
//posP为模式串的扫描指针,posT为目标串的扫描指针int posP=0,posT=k;//lengthP为模式串的长度,lengthT为目标串的长度int lengthP = pat.curLength;int lengthT = curLength;//下面做法与求next[i]相同,只不过求next[i]是模式串与自身匹配while(posP<lengthP && posT< lengthT){ if(posP==-1 || pat.ch[posP]==ch[posT]){ posP++;posT++; } else{ //next[posP]表示模式串前posP个字符中,前缀的后一个字符的下标。 //其中前缀指模式串前posP个字符中前面与后面最大相同部分。 posP=next[posP]; }}//posP<lengthP表示目标串先于模式串扫描完。if(posP<lengthP){ return -1;}else{ //此时posT指向满足模式串部分的下一个字符,减去模式串长度即为满足部分的首字符下标。 return posT-lengthP;}
3.小结
字符串操作中最难的部分就是模式匹配中的KMP算法,如果不考虑效率问题,可以使用简单模式匹配算法实现该功能。
KMP算法的关键在于理解next[i]中存放的是什么。个人对这个有2种理解:第一、next[i]表示前i个字符中前面与后面最大相同部分的长度;第二、next[i]表示前i个字符中前面与后面最大相同部分的下一个字符的下标。
在代码实现中,我认为第二种更容易理解代码。
能力有限,KMP算法这部分真的很难仅通过文字来表述,个人又嫌作图麻烦,所以只能讲到这种程度了。
四、C++中的string类
总结一下,字符串的本质就是把一堆字符类型的东西放在了一起而已(不管是用数组、动态数组还是链表等)。对字符串的操作,其本质就是对单个字符的操作(便于理解可以直接想像成字符数组)。上面讲了这么多,只是想把各种操作的实现归结于循环和选择这两个本质结构。
对于使用而言,C++的string类显得十分方便。
1.赋值和复制(=)
2.判断相等或不等(!= ==)
3.字符串长度(length())
4.连接(+)
5.取子串(substr())
6.存取单一字符([ ])
7.查找某个字符或字符串(find())
8.插入(insert())
9.删除(erase())
10.替换(replace())
上述函数都有好几种参数形式,熟练掌握适合自己的参数形式,可以在字符串处理上,大幅度提高效率。
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- 处理字符串
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- 字符串处理
- sed
- Java应用基础进阶——GPS数据处理
- Mac下安装pip和pylint遇到的坑
- Java程序为何“编译一次,到处运行”?
- form表单登录异步ajax校验
- 字符串处理
- Floor 1:TensorFlow安装两步行【Windows篇】
- Codeforces 591E
- python中list/tuple/dict/set的区别
- fifo实现单服务器多客户端
- 转载 并查集(超级超级棒)
- JAVA | 14
- 这是抱怨吗?或许是吧!
- JavaMail开发教程01开山篇