C++初阶-string类的简单应用
目录
1.仅仅反转字母
2.字符串中第一个唯一字符
3.字符串最后一个单词的长度
4.验证回文串
5.字符串相加
6.总结
1.仅仅反转字母
题目链接:https://leetcode.cn/problems/reverse-only-letters/description/
在数据结构中我们学了一种方法叫做前后指针法,这个在快速排序中也有讲过,需要的可以见我的数据结构篇的快速排序前后指针法,而这个题目仅仅就是把这个改为了string而已,我们只要分情况讨论即可解答该题:
#include<string>
class Solution
{
public:bool iszimu(char& a){if((a>='a' && a<='z')||(a>='A' && a<='Z')){return true;}return false;}string reverseOnlyLetters(string s) {//判断是否为空if(s.empty()){return s;}int begin=0;int end=s.size()-1;while(begin<end){while(begin<end && !iszimu(s[begin])){++begin;}while(begin<end && !iszimu(s[end])){--end;}//std标准库里面的swap(s[begin],s[end]);++begin;--end;}return s;}
};
我们做这个题目的时候看一遍是不会的,因为基本上没做过这种题目,所以很正常,思想也和之前一样(快速排序),就不过多讲解了!
2.字符串中第一个唯一字符
题目链接:https://leetcode.cn/problems/first-unique-character-in-a-string/description/
我们看到这个东西就是和我们的计数排序(非比较排序的思想一样),主要是注意这句话:
也就是说我们只要遍历一遍就可以找出来了,代码如下:
class Solution
{
public:int firstUniqChar(string s) {int arr[27]={0};string::iterator it1=s.begin();while(it1!=s.end()){arr[*it1-'a']++;it1++;}//错误写法//int i;//for(i=0;i<27;i++)//{// if(arr[i]==0)// {// return i;// }//}//正确写法for(int i=0;i<s.size();i++){if(arr[s[i]-'a']==1){return i;}}return -1;}
};
注意:这里我们需要寻找的是从开始找的第一个只出现一次的字符,所以我们不能写成那样的;此外我这种方法是迭代器的遍历方法,也可以用范围for和普通的写法,这个只要掌握一下string类里面的size函数的用法即可!
3.字符串最后一个单词的长度
题目链接:https://www.nowcoder.com/practice/8c949ea5f36f422594b306a2300315da?tpId=37&&tqId=21224&rp=5&ru=/activity/oj&qru=/ta/huawei/question-ranking
这个题目其实我想在讲getline函数时就讲了,这个就是getline函数和rfind函数(我自己差点也忘记这个函数了)的应用了!
#include <iostream>
#include<string>
using namespace std;
int main()
{
string a;
while(getline(cin,a))
{size_t pos=a.rfind(' ');//a.size()-1是真实长度//而再减去剩余的长度即真实长度//因为rfind是返回找到的元素的下标(若为字符串则返回最前的一个元素下标)cout<<a.size()-pos-1<<endl;
}
}
4.验证回文串
题目链接:
125. 验证回文串 - 力扣(LeetCode)
这个题目难度还行,我们需要先把字符串的大写字母转小写,然后再前后指针遍历,如果一直是相同的(除去其他字符外),则是回文串。
class Solution
{
public:bool iszimu(char& a){if(a>='a' && a<='z'){return true;}if(a>='A' && a<='Z'){return true;}if(a>='0' && a<='9'){return true;}return false; }bool isPalindrome(string s) {if(s.empty()){return true;}for(int i=0;i<s.size();i++){if(s[i]>='A' &&s[i]<='Z'){//大写是比小写的ASCII码值小的(我想了好久)s[i]+=32;}}int begin=0;int end=s.size()-1;while(begin<end){while(begin<end && !iszimu(s[begin])){++begin;}while(begin<end && !iszimu(s[end])){--end;}if(s[begin]==s[end]){begin++;end--;}else{return false;}}return true;}
};
这里有很多注意的点,比如大写转为小写,要+=32,而不是-=26,这个东西很容易就会忘记;还有我们可以直接
return (a>='A'&&a<='Z')||
(a>='a' && a<='z') ||
(a>='0' && a<='9');
这样执行时间就是0ms了!
5.字符串相加
题目链接:
415. 字符串相加 - 力扣(LeetCode)
这个题目非常经典,所以比较重要!我们思路是:
从最后去字符,然后将二者-‘0’再相加,如果小于10就直接把结果+‘0’尾插,否则把后面的数字+‘0’尾插,并且把1进到前面一位(用临时变量),代码如下:
class Solution
{
public:string addStrings(string num1, string num2) {string str;int end1=num1.size()-1;int end2=num2.size()-1;int next=0;while(end1>=0 ||end2>=0){int x1=end1>=0? num1[end1--]-'0':0;int x2=end2>=0? num2[end2--]-'0':0;int ret=x1+x2+next;next=ret/10;ret=ret%10;str+=('0'+ret);}if(next==1){str+='1';}reverse(str.begin(),str.end());return str;}
};
6.总结
这讲的题目比较经典,所以提前讲了,之后在把string类手动实现后我将讲解一些扩展的string题目,下节将讲解:string类的手动实现。喜欢的可以一键三连哦,下讲再见!