【C/C++】速通涉及string类的经典编程题
- 一.字符串最后一个单词的长度
- 代码实现:(含注释)
- 二.验证回文串
- 解法一:
- 代码实现:(含注释)
- 解法二:(推荐)
- 1. 函数isalnum介绍:
- 2. 函数tolower介绍:
- 3. 代码实现:
- 三.翻转字符串II:区间部分翻转
- 代码实现:(含注释)
- 四.翻转字符串III:翻转字符串中的单词
- 代码实现:(含注释)
一.字符串最后一个单词的长度
本题牛客网链接:
原理:从字符串最后倒着往前遍历,遇到第一个空格标记其下标
代码实现:(含注释)
#include <iostream>
using namespace std;
#include <string>
int main() {
string s;
getline(cin, s);//读取一整行数据,遇到空格或“\0”照样读取
int ret = s.rfind(' ', s.size() - 1);
if(ret == s.size())//只有一个字符时
printf("%lld",ret);
else
printf("%lld",(s.size() - 1 - ret));
}
二.验证回文串
本题LeetCode链接:
解法一:
原理:先将字符串中大写字符转化为对应小写字符,然后将数字和字符(注意不可拷贝空格)拷贝到tmp对象中,用双指针分别从tmp对象首尾开始向字符串中间遍历,遍历过程中判断两指针指向字符是否相等
代码实现:(含注释)
class Solution {
public:
bool isPalindrome(string s) {
string tmp;
//将大写字母转化为小写
for (int i = 0; i < s.size(); i++)
{
if (s[i] >= 'A' && s[i] <= 'Z')
{
s[i] += 32;
}
}
int k = 0;
for (int k = 0; k < s.size(); k++)//看题看题!!!字符和数字都要拷贝到tmp中
{
if ((s[k] >= 'a' && s[k] <= 'z') ||(s[k] >= '0' && s[k] <= '9')
&& s[k] != ' ' )
tmp += s[k];
}
//双指针法
int begin = 0, end = tmp.size() - 1;
while (begin < end)
{
if (tmp[begin] != tmp[end])
return false;
begin++;
end--;
}
return true;
}
};
解法二:(推荐)
原理:充分运用库函数的特性,再结合反向迭代器
1. 函数isalnum介绍:
- 函数原型:bool isalnum(auto ch);
- 函数功能:
(1) 检查范围:isalnum函数检查传入的字符是否属于字母(大写或小写)或数字(0-9)的ASCII码范围。
(2)返回值:如果字符是字母或数字,则返回非零值(通常为真值);否则,返回零(表示假值)。
2. 函数tolower介绍:
- 函数原型:auto tolower(auto ch);
- 函数功能:将大写字母转换为小写字母。
3. 代码实现:
class Solution {
public:
bool isPalindrome(string s) {
string tmp;
for(auto ch : s)
{
if(isalnum(ch))//函数isalnum
{
tmp += tolower(ch);//函数tolower
}
}
string tmp_rev(tmp.rbegin(), tmp.rend());
return tmp == tmp_rev;
}
};
三.翻转字符串II:区间部分翻转
本题LeetCode链接:
原理:充分运用reverse函数,特殊情况特殊处理,注意把控区间边界
代码实现:(含注释)
class Solution {
public:
string reverseStr(string s, int k) {
int ps = 0;
if(k > s.size())//特殊情况一
{
reverse(s.begin(), s.end());
return s;
}
if(ps + 2*k > s.size())//特殊情况二
{
reverse(s.begin(), s.begin() + k);
return s;
}
while (ps + 2*k <= s.size())//边界问题等于不可少
{
reverse(s.begin() + ps, s.begin() + ps + k);
ps += 2 * k;
if (ps + k > s.size())
{
reverse(s.begin() + ps, s.end());
}
if (ps + 2 * k > s.size() && ps + k <= s.size())//边界问题等于不可少
{
reverse(s.begin() + ps, s.begin() + ps + k);
}
}
return s;
}
};
四.翻转字符串III:翻转字符串中的单词
本题LeetCode链接:
原理:充分运用reverse函数,首尾单词特殊处理,注意区间边界
代码实现:(含注释)
class Solution {
public:
string reverseWords(string s) {
int len = 0;//单词的长度
int k = 0;//单词首字母下标
for(int i = 0; i < s.size(); i++)
{
if(k == 0 && s[i] == ' ')//解决第一个单词的颠倒
{
len = i - k;
reverse(s.begin() + k, s.begin() + k + len );
k = i;
}
if(s[i] == ' ' )//解决中间单词的颠倒
{
len = i - k + 1;
reverse(s.begin() + k , s.begin() + k + len );
k = i;
}
}
//解决最后一个单词的颠倒
int j = s.rfind(' ', s.size() - 1);
reverse(s.begin() + j + 1, s.end());
return s;
}
};