算法入门 - 字符串
1. 替换空格
随着空格被填充后,旧尾指针和新尾指针的差距进一步缩减,直至填充完毕,前后指针指向同一个位置随即遍历结束。这是该解法的精髓。
class Solution {
public:
//前后指针的解法,分别指向新的尾和旧的尾。利用旧尾向前遍历,
// 遇到其他元素则后移2位,遇到空格元素则用新尾指针倒序填入%20,
//随着空格被填充后,旧尾指针和新尾指针的差距进一步缩减,直至填充完毕,前后指针指向同一个位置随即遍历结束。
void replaceSpace(char *str,int length) {
int cnt = 0;
//计算空格个数
for (int i = 0; i < strlen(str); i++) {
if (str[i] == ' ') {
cnt++;
}
}
int new_end = strlen(str) + 2 * cnt;
int old_end = strlen(str);
while (old_end < new_end) {
if (str[old_end] == ' ') {
str[new_end--] = '0';
str[new_end--] = '2';
str[new_end--] = '%';
old_end--;
}
else {
str[new_end--] = str[old_end--];
}
}
}
};
2. 字符串左旋
class Solution {
public:
string LeftRotateString(string str, int n) {
if (str.size() < 2) {
return str;
}
n %= str.size(); //非常重要
if (n == str.size()) {
return str;
}
while (n--) {
char c = str[0];
for (size_t i = 1; i < str.size(); i++) {
str[i -1] = str[i];
}
str[str.size() - 1] = c;
}
return str;
}
};
class Solution {
public:
string LeftRotateString(string str, int n) {
while (n--) {
str.push_back(*str.begin());
str.erase(str.begin());
}
return str;
}
};
双倍串
class Solution {
public:
//abc123abc123
// bc123a -- 1
string LeftRotateString(string str, int n) {
if (str.size() < 2) {
return str;
}
n %= str.size();
return str.substr(n) + str.substr(0, n);
}
};
3. 子串逆置
划分逆置区间
class Solution {
public:
//先整体逆置,再逆置单词
string ReverseSentence(string str) {
if (str.size() == 0) {
return str;
}
reverse(str.begin(), str.end());//整体逆置
size_t l = 0;
while (l < str.size()) {
size_t r = str.find(' ', l); //查找空格位置,并确定区间[l,r)
if (r == string::npos) {
reverse(str.begin() + l, str.end());
break;
}
reverse(str.begin() + l, str.begin() + r); //逆置单词
l = r + 1;
}
return str;
}
};
利用栈结构
class Solution {
public:
//利用栈的先入后出的特性,将每个单词序列按顺序入栈,在反着出到字符串中。
//注意查找要记得指定最前位置,提取子串是指定首位和长度
string ReverseSentence(string str) {
if (str.size() < 2) {
return str;
}
stack<string> st; //利用栈的先入后出
int begin = 0, end = str.find(' '); //单词区间[begin,end)
while (end != string::npos) {
st.push(str.substr(begin, end - begin)); //查找子串并入栈
begin = end + 1; //进位
end = str.find(' ', begin);
}
st.push(str.substr(begin)); //将最后一个单词入栈
str.clear(); //清空原字符串
while (!st.empty()) {
str += st.top() += ' '; //将栈中所有元素出到str中并补齐空格
st.pop();
}
str.pop_back(); //把最后一个多余的空格删去
return str;
}
};
4 . 回文串判定和修改
//只要想清楚,在遍历过程中,当发现头尾指针指向的位置不相等时,就可以删除一个再判断当前字符串是否是回文串,
//如果是,则返回删除的下标,如果不是,则返回另一个位置的下标。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int IsPalindrome(string& str) {
int begin = 0, end = str.size() - 1;
while (begin < end) {
if (str[begin] != str[end]) {
return begin;
}
begin++;
end--;
}
return -1;
}
int main() {
int times;
cin >> times;
while (times--) {
string str;
cin >> str;
int i = IsPalindrome(str);
if (i == -1) {
cout << -1 << endl;
}
else {
str.erase(i, 1);
if (IsPalindrome(str) == -1) {
cout << i << endl;
}
else {
cout << str.size() - i << endl;//已被删除一个元素
}
}
}
return 0;
}