344反转字符串
class Solution {
public:
void reverseString(vector<char>& s) {
int head_index = 0;
int back_index = s.size()-1;
while(head_index<back_index) {
char temp = s[head_index];
s[head_index++] = s[back_index];
s[back_index--] = temp;
//位运算交换 不用中间变量
// ^ 异或运算符 从ascii码转为二进制进行异或操作
s[head_index] ^= s[back_index];
s[back_index] ^= s[head_index];
s[head_index] ^= s[back_index];
head_index++;
back_index--;
}
}
};
541反转字符串2
- 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。 - 每计数至
2k
个字符,就反转这2k
字符中的前k
个字符
要想到这两种情况其实是一种处理
for(int i=0;i<s.size();i+=2*k) {
if(i+k<s.size()) {
reverse(s.begin()+i,s.begin()+i+k);
}
else {
reverse(s.begin()+i,s.end());
}
}
return s;
卡码54替换数字
class solution {
public:
void solu(string& s,int number_len) {
int old_index = s.size()-1;
s.resize(s.size()+number_len*5); //要把原来的数字去了
int new_index = s.size()-1;
for(;old_index>=0;old_index--) {
if(s[old_index]>='0'&&s[old_index]<='9') {
s[new_index--] = 'r';
s[new_index--] = 'e';
s[new_index--] = 'b';
s[new_index--] = 'm';
s[new_index--] = 'u';
s[new_index--] = 'n';
}else {
s[new_index--] = s[old_index];
}
}
}
};
int main() {
solution sl;
string s;
while(cin>>s) {
int count=0;
for(int i=0;i<s.size();i++) {
if(s[i]>='0'&&s[i]<='9') {
count++;
}
}
sl.solu(s,count);
cout<<s<<endl;
}
std::cout << "Hello, World!" << std::endl;
return 0;
}
(*需要二刷)151反转字符串中的单词
class Solution {
public:
//分三步
//1去除多余空格
//2整体反转
//3单词再反转
void removeExtraSpaces(string& s) {
int slow = 0;
for(int i=0;i<s.size();i++) {
if(s[i]!= ' ' ) {
if(slow!=0)s[slow++]=' ';
while(i<s.size()&&s[i]!=' ') {
s[slow++] = s[i++];
}
}
}
s.resize(slow);
}
void reverse(string& s,int start,int end) {
for(int i=start,j=end;i<j;i++,j--) {
swap(s[i],s[j]);
}
}
string reverseWords(string s) {
removeExtraSpaces(s);
reverse(s,0,s.size()-1);
int start =0;
for(int i=0;i<=s.size();i++) {
if(s[i]==' '|| i==s.size()) {
reverse(s,start,i-1);
start = i+1;
};
}
return s;
}
};
卡码55右旋转字符串
#include <iostream>
#include<string>
using namespace std;
void reverse(string &s,int beg,int end) {
for(int i=beg,j=end;i<(beg+end+1)/2;i++,j--) {
swap(s[i],s[j]);
}
}
void right_reverse(string &s,int len) {
int s_len = s.size();
reverse(s,0,s_len-1);
reverse(s,0,len-1);
reverse(s,len,s_len-1);
}
int main() {
while(true) {
int len;
cin>>len;
string s;
cin>>s;
right_reverse(s,len);
for(char i:s) {
cout<<i;
}
}
}
28. 找出字符串中第一个匹配项的下标
暴力解法
就不写了挨个配错误了从头开始
KMP
难点主要在于next表的制作,首先得知道next表的作用,就是当匹配失败时,通过检查前一项的next表值重新检测匹配。next表的制作思路如下
int* findNext(string needle) {
//next表就是当字串匹配时,如果当前字符没匹配上
//可以通过对应next表的前一位找到最长公共前后缀匹配串
int next[needle.size()];
int j=0;
next[0]=0;
for(int i=1;i<needle.size();i++) {
//这个过程可以看成是把 (i-j)--i的这一个字串单独拿出和0--j的这一个字串做匹配
//配上了j++
//没配上就通过next表前一位也就是j-1再去找更短的最长公共前后缀匹配
while(j>0&&needle[i]!=needle[j])j = next[j-1]; //这就是缩短最长公共前后缀的个数的过程
if(needle[i]==needle[j])j++;
next[i]=j;
}
return next;
}
int strStr(string haystack, string needle) {
if(needle.size()==0)return 0;
int *next =findNext(needle);
int j=0;
for(int i=0;i<haystack.size();i++){
while(j>0&&haystack[i]!=needle[j])j=next[j-1];
if(haystack[i]==needle[j])j++;
if(j==needle.size())return i-needle.size()+1;
}
return -1;
}
459. 重复的子字符串
暴力解
//暴力解法
class Solution {
public:
bool repeatedSubstringPattern(string s) {
string k;
for(int i=0;i<s.size()/2;i++) {
k.push_back(s[i]);
if(s.size()%(i+1)!=0)continue;
bool flag =true;
for(int j=i+1;j<s.size();j++) {
if(s[j]!=k[j%k.size()]) {
flag =false;
break;
}
}
if(flag){return true;}
}
return false;
}
};
头尾相接
//头尾相接
class Solution1 {
public:
bool repeatedSubstringPattern(string s) {
string k = s+s;
k = k.substr(1,s.size()*2-2);
if(k.find(s)!=string::npos)return true;
return false;
}
};
KMP
class Solution2 {
public:
void getNext(int* next,string s) {
int j=0;
next[0] = 0;
for(int i=1;i<s.size();i++) {
while(s[j]!=s[i]&&j>0)j=next[j-1];
if(s[j]==s[i])j++;
next[i] = j;
}
}
bool repeatedSubstringPattern(string s) {
if(s.size()==0)return false;
int next[s.size()];
int len = s.size();
getNext(next,s);
if(next[s.size()-1]!=0&&(len%(len-(next[len-1])))==0)return true;
return false;
}
};