前言
感觉字符串这里主要应用的是双指针和KMP算法,等这一遍过完一定要再来一遍KMP算法
一、翻转字符串
采用双指针的思路。
len = nums.size();
for( i = 0, j = lens-1; i < lens/2; i++,j--){
swap(nums[i],nums[j]);
}
二、翻转字符串II
adnjfdnfsdj k=2
danjdfnfdsj
每2k为一个周期,一个周期中前k个元素进行翻转
伪代码:
for(i = 0; i < s.size(); i += 2k ){ //找2k区间即翻转区间的起点,在对翻转区间进行操作会更简单
if(i + k <= s.size){ //如果可翻转区域全在字符串内,则正常翻转
reverse(s,i,i+k);
continue;
}
reverse(s,i,s.size());//否则,直接翻转最后一个区间起点到终点全部元素即可
}
三、翻转字符串III
string s = “ hello world”
return “world hello”
只翻转单词并且首词前不能有空格,单词间只能有一个空格
难点:清除多余的空格(利用双指针)
int slow = 0;
for(int fast = 0; fast < s.size(); fast++){
if(s[fast] != ‘_’){//首先检测单词,一旦检测到单词,便将整个单词录入
if(s[slow] != ‘_’) s[slow++]=’_’; //慢指针所在不是空格,说明慢指针在一个词尾,因此创建一个空格,为下一个单词做准备
while(fast < s.size() && s[fast] != ‘ ’){ //完整录入一个单词
s[slow] = s[fast];
fast++;
slow++;
}
}
}
四、KMP算法
KMP算法
主要用于解决字符串匹配问题
给出一个文本串”aabaabaaf”和模式串”aabaaf”,检测文本串中是否出现过模式串
前缀:包含首字母不包含尾字母的所有子串
后缀:只包含尾字母不包含首字母的所有子串
例如这个问题:
子串 a aa aab aaba aabaa aabaab
最长相等前后缀 0 1 0 1 2 0
得到模式串的前缀表:010120.
在匹配时,找到冲突的字母f,找前面子串的最长相等前后缀,即为2.,意味着有一个后缀aa,前面有一个前缀aa与他相等,就从这个前缀后面重新开始匹配(前缀aa开始的串不匹配,就从后缀开始的aa开始进行匹配)。
此题是这三个步骤。
①初始化next数组和各个变量
②处理前后缀不同的情况
③处理前后缀相同情况
next
void getnext(Next,s){ //指针j指向前缀末尾位置,指针i指向后缀末位位置
j = 0;
next [0]=0;//首位没有前后缀,记为0
for(int i = 1; i < s.size(); i++){
while(j > 0 && s[i] != s[j]){
j = next[j-1];//前后缀一旦不同,开始退回
}
if(s[i] == s[j]){//前后缀相同,在上一步的基础上加一,即为这一步的最长前后缀长度
j++;
}
next[i] = j;
}