个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创C++string类相关OJ练习(1)
收录于专栏【C++语法基础】
本专栏旨在分享学习C++的一点学习笔记,欢迎大家在评论区交流讨论💌
目录
1.仅仅反转字母
题目链接:917. 仅仅反转字母 - 力扣(LeetCode)
题目描述:
给你一个字符串 s
,根据下述规则反转字符串:
- 所有非英文字母保留在原有位置。
- 所有英文字母(小写或大写)位置反转。
返回反转后的 s
。
示例 1:
输入:s = "ab-cd" 输出:"dc-ba"
示例 2:
输入:s = "a-bC-dEf-ghIj" 输出:"j-Ih-gfE-dCba"
示例 3:
输入:s = "Test1ng-Leet=code-Q!" 输出:"Qedo1ct-eeLg=ntse-T!"
提示
1 <= s.length <= 100
s
仅由 ASCII 值在范围[33, 122]
的字符组成s
不含'\"'
或'\\'
解题思路:
1.定义begin和end两个指针,begin从头开始扫描,end从尾开始扫描
2.定义isLetter函数,判断该字符是否需要交换
3.当begin<end时开始循环扫描,经过函数isLetter判断后交换,交换后,begin++,end--
class Solution {
public:
bool isLetter(char ch)
{
if(ch >= 'a' && ch <= 'z')
return true;
if(ch >= 'A' && ch <= 'Z')
return true;
return false;
}
string reverseOnlyLetters(string s) {
if(s.empty())
return s;
int begin = 0, end = s.size() - 1;
while(begin < end)
{
while(begin < end && !isLetter(s[begin]))
++begin;
while(begin < end && !isLetter(s[end]))
--end;
swap(s[begin++], s[end--]);
}
return s;
}
};
2.字符串中的第一个唯一字符
OJ链接:387. 字符串中的第一个唯一字符 - 力扣(LeetCode)
题目描述:
给定一个字符串 s
,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1
。
示例 1:
输入: s = "leetcode" 输出: 0
示例 2:
输入: s = "loveleetcode" 输出: 2
示例 3:
输入: s = "aabb" 输出: -1
提示:
1 <= s.length <= 105
s
只包含小写字母
解题思路:
定义一个数组a[26] = {0},用for范围遍历s,用a数组存贮string s中的所有字符减去'a'的值(用a数组记录每个字符出现的次数),最后在遍历s一遍,当a[s[i]-'a'] == 1时,即字符串中的第一个唯一字符.
class Solution {
public:
int firstUniqChar(string s) {
int a[26] = {0};
for(auto e : s)
{
a[(e-'a')]++;
}
for(size_t i = 0; i < s.size(); i++)
{
if(a[s[i] - 'a'] == 1)
return i;
}
return -1;
}
};
3. 字符串最后一个单词的长度
OJ链接:字符串最后一个单词的长度_牛客题霸_牛客网 (nowcoder.com)
题目描述:
描述
计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)
输入描述:
输入一行,代表要计算的字符串,非空,长度小于5000。
输出描述:
输出一个整数,表示输入字符串最后一个单词的长度。
示例1
输入:hello nowcoder
输出:8
说明:最后一个单词为nowcoder,长度为8
解题思路:
1.这道题不能使用cin>>line,因为它会遇到空格就结束了,可以使用getline(cin, line)
2.这里需要使用string中的rfind,找到最后一个空格的位置
代码展示:
#include <iostream>
#include <string>
using namespace std;
int main() {
string line;
//不要使用cin>>line,因为它会遇到空格就结束了
//while(cin>>line)
while(getline(cin, line))
{
//用rfind找到最后一个空格的位置
size_t pos = line.rfind(' ');
cout << line.size() - pos - 1 << endl;
}
return 0;
}
4.验证回文字符串
OJ链接:125. 验证回文串 - 力扣(LeetCode)
题目描述:
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s
,如果它是 回文串 ,返回 true
;否则,返回 false
。
示例 1:
输入: s = "A man, a plan, a canal: Panama" 输出:true 解释:"amanaplanacanalpanama" 是回文串。
示例 2:
输入:s = "race a car" 输出:false 解释:"raceacar" 不是回文串。
示例 3:
输入:s = " " 输出:true 解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。 由于空字符串正着反着读都一样,所以是回文串。
提示:
1 <= s.length <= 2 * 105
s
仅由可打印的 ASCII 字符组成
解题思路:
1.写一个函数isLetterOrNumber判断是否尾字母数字字符
2.将小写字符转换成大写字符
3.定义两个指针begin和end分别从开始和结尾开始扫描,循环条件为begin<end,首先要通过isLetterOrNumber函数判断是否合法,不合法直接跳过,直到两个指针全部指向合发字符,然后判断是否相等,不相等直接返回false,直到循环结束,没有返回false,那这个字符串就是回文结构,返回true
class Solution {
public:
bool isLetterOrNumber(char ch)
{
return (ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z');
}
bool isPalindrome(string s) {
for(auto& ch : s)
{
if(ch >= 'A' && ch <= 'Z')
ch += 32;
}
int begin = 0, end = s.size()-1;
while(begin < end)
{
while(begin < end && !isLetterOrNumber(s[begin]))
++begin;
while(begin < end && !isLetterOrNumber(s[end]))
--end;
if(s[begin] != s[end])
{
return false;
}
else
{
++begin;
--end;
}
}
return true;
}
};
5.字符串相加
OJ链接:415. 字符串相加 - 力扣(LeetCode)
题目描述:
给定两个字符串形式的非负整数 num1
和num2
,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger
), 也不能直接将输入的字符串转换为整数形式。
示例 1:
输入:num1 = "11", num2 = "123" 输出:"134"
示例 2:
输入:num1 = "456", num2 = "77" 输出:"533"
示例 3:
输入:num1 = "0", num2 = "0" 输出:"0"
提示:
1 <= num1.length, num2.length <= 104
num1
和num2
都只包含数字0-9
num1
和num2
都不包含任何前导零
解题思路:
1.模拟两个整数相加,用next表示进位
2.取两个string的size()-1,end1和end2,进入while(end1 >= 0 || end2 >= 0)循环,模拟两个数相加的过程
class Solution {
public:
string addStrings(string num1, string num2) {
int end1 = num1.size()-1;
int end2 = num2.size()-1;
string str;
int next = 0;//进位
while(end1 >= 0 || end2 >= 0)
{
//如果里面最后的数是大于等于0,那将它转换成整数进行计算,否则直接赋值为0
int x1 = end1 >= 0 ? num1[end1--] - '0' : 0;
int x2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//记录换算过程
int x= x1 + x2 + next;
//处理进位
next = x / 10;
x %= 10;
//头插
str.insert(str.begin(), '0' + x);
}
if(next == 1)
{
str.insert(str.begin(), '1');
}
return str;
}
};
6.总结
如果你想彻底了解C++string类,做一些OJ题是必不可少的步骤,这五到经典OJ题希望可以给到你们帮助,不要忘记了点赞👍 收藏✨ 留言✉ 加关注💓哦!
后面我也会抓紧更新第二期,大家可以订阅[C++语法学习]