虫子 STL string 下 练习题
【摘要】 4.string类对象的修改操作函数名称功能说明push_back在字符串后尾插字符cappend在字符串后追加一个字符串operator+= (重点)在字符串后追加字符串strc_str(重点)返回C格式字符串find + npos(重点)从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置substr在s...
4.string类对象的修改操作
函数名称 功能说明 push_back 在字符串后尾插字符c append 在字符串后追加一个字符串 operator+= (重点) 在字符串后追加字符串str c_str(重点) 返回C格式字符串 find + npos(重点) 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置 rfind 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置 substr 在str中从pos位置开始,截取n个字符,然后将其返回 注意:
- 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
- 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
int main() { string s; s.push_back('h'); s.push_back('e'); s.push_back('l'); s.push_back('l'); s.push_back('o'); cout << s << endl; s.append(" world"); cout << s << endl; string s2 = "!!!!!!"; s.append(s2); cout << s << endl; //但是不巧的是实际中最喜欢用的是+= string s3; s3 += 'X'; s3 += "你好"; s3 += s2; cout << s3 << endl; //尽量少用insert,因为底层实现是数组,头部或者中间需要挪动数据 s3.insert(0, "x"); s3.insert(0,"hhhh"); cout << s3 << endl; //删除 string s4 = s3; string s5 = s3; string s6 = s3; s4.erase(3, 100);//从第三个开始删除 s5.erase(3);//从第三个开始删除,一直删完 s6.erase(); //直接删光 cout << s4 << endl; cout << s5 << endl; cout << s6 << endl; return 0; }
int main() { string s("Hello world"); cout << s << endl; //这边调的是operator<<(cout,s); cout << s.c_str() << endl;//这边调用的是内置类型operator<<(cout,const char*); s.resize(20); s += "!!!"; cout << s << endl; cout << s.c_str() << endl; return 0; }
int main() { //假设我们需要取文件名的后缀 string filename = "text.txt.zip"; size_t pos = filename.rfind('.'); if (pos != string::npos) { string suff(filename, pos); cout << suff << endl; } return 0; }
//取域名 string GetDomain(const string& url) { size_t pos = url.find("://"); if (pos != string::npos) { //找到域名的最开始位置 size_t start = pos + 3; //从域名开始的位置向后面找 ’/‘ size_t end = url.find('/', start); if (end != string::npos) { return url.substr(start, end - start); } } //假如没有就返回一个匿名对象 return string(); } //取协议 string GetProtocol(const string& url) { size_t pos = url.find("://"); if (pos != string::npos) { return url.substr(0, pos); } //假如没有就返回一个匿名对象 return string(); } int main() { //分别取出域名和协议名 string url1 = "http://www.cplusplus.com/reference/string/string/find/"; string url2 = "https://juejin.cn/creator/home"; cout << GetDomain(url1) << endl; cout << GetProtocol(url1) << endl; cout << GetDomain(url2) << endl; cout << GetProtocol(url2) << endl; return 0; }
5.string类非成员函数
函数 功能说明 operator+ 尽量少用,因为传值返回,导致深拷贝效率低 operator>> (重点) 输入运算符重载 operator<< (重点) 输出运算符重载 getline (重点) 获取一行字符串 relational operators (重点) 大小比较
几题小菜
找字符串中第一个只出现一次的字符
用这题来练手3种遍历
下标+[]
class Solution { public: int firstUniqChar(string s) { //26个字母计数数组 int count[26] = {0}; int i= 0; //遍历计数 for(i = 0;i<s.size();i++) { count[s[i]-97]++; } //找第一个是1的 for(i = 0;i<s.size();i++) { if(1 == count[s[i]-97]) return i; } return -1; } };
迭代器
class Solution { public: int firstUniqChar(string s) { //26个字母计数数组 int count[26] = {0}; //迭代器 string::iterator it = s.begin(); while(it != s.end()) { count[*it-97]++; it++; } //找第一个是1的 for(int i = 0;i<s.size();i++) { if(1 == count[s[i]-97]) return i; } return -1; } };
范围for
class Solution { public: int firstUniqChar(string s) { //26个字母计数数组 int count[26] = {0}; //范围for for(auto& e:s) { count[e-97]++; } //找第一个是1的 for(int i = 0;i<s.size();i++) { if(1 == count[s[i]-97]) return i; } return -1; } };
仅仅反转字母
class Solution { public: //判断是否是字母 bool isletter(const char ch) { if((ch >= 'a' && ch<='z') ||(ch >= 'A' && ch <='Z')) return true; return false; } string reverseOnlyLetters(string s) { if(!s.size()) 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]); begin++; end--; } return s; } };
字符串最后一个单词的长度
#include <iostream> using namespace std; int main() { string str; getline(cin,str); size_t pos = str.rfind(' '); if(pos != string::npos) { cout<< str.size()-pos-1<<endl; } else { cout<< str.size()<<endl; } return 0; }
验证回文串
class Solution { public: bool isPalindrome(string s) { //创建两个空字符串 string str1,str2,str3; //反向迭代器 string::reverse_iterator rit = s.rbegin(); while(rit != s.rend()) { if(*rit >= 'A' && *rit <='Z') str1 += *rit+32; else if(*rit >= 'a' && *rit<='z') str1 += *rit; else if(*rit >= '0' && *rit<='9') str1 += *rit; rit++; } str2 = str1; //再来一次反向迭代器 string::reverse_iterator rt = str2.rbegin(); while(rt != str2.rend()) str3 += *rt++; if(str3 == str2) return true; else return false; } };
class Solution { public: //判断字母数字 bool islettername(const char& ch){ if(ch >= 'a' && ch <= 'z' || (ch >= '0' && ch <='9')) return true; return false; } bool isPalindrome(string s) { //先把s里面大写全部改成小写的 for(auto& e:s) { if(e>='A' && e<='Z') e+=32; } int begin = 0; int end = s.size()-1; while(begin < end) { while(begin < end && !islettername(s[begin])) begin++; while(begin < end && !islettername(s[end])) end--; if(s[begin] == s[end]) { begin++; end--; } else return false; } return true; } };
字符串相加
class Solution { public: string addStrings(string num1, string num2) { //两个下标 int end1 = num1.size()-1,end2 = num2.size()-1; //计算后的对象 string ansStr; //进位 int carry = 0; while(end1>=0 || end2>=0) { int n1 = 0; if(end1 >= 0){ n1 = num1[end1] - '0'; end1--; } int n2 = 0; if(end2 >= 0){ n2 = num2[end2] - '0'; end2--; } //两个位置开始相加 int ret = n1+n2+carry; if(ret > 9){ ret -= 10; carry = 1; } else carry = 0; //这是就准备插字符 ansStr.insert(0,1,ret+'0'); } //插最后一个进位的 if(carry) ansStr.insert(0,1,carry+'0'); return ansStr; } };
==实际上我们可以看到提交时间看到我们时间复杂度不行,那是因为我们头插了insert了,字符串越长,挪动的就越恶心,也就效率越低,所以我就直接尾插,到最后再来个逆置reverse就行了,这时候就看我们选用的接口了,基本一题都有好几种解法==
class Solution { public: string addStrings(string num1, string num2) { //两个下标 int end1 = num1.size()-1,end2 = num2.size()-1; //计算后的对象 string ansStr; //进位 int carry = 0; while(end1>=0 || end2>=0) { int n1 = 0; if(end1 >= 0){ n1 = num1[end1] - '0'; end1--; } int n2 = 0; if(end2 >= 0){ n2 = num2[end2] - '0'; end2--; } //两个位置开始相加 int ret = n1+n2+carry; if(ret > 9){ ret -= 10; carry = 1; } else carry = 0; //这是就准备插字符 我们这就直接尾插 ansStr += (ret +'0'); } //插最后一个进位的 if(carry) ansStr += (carry +'0'); //然后逆置就行 reverse(ansStr.begin(),ansStr.end()); return ansStr; } };
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)