【C++】继续学习 string类 吧

简介: 首先不得不说的是由于历史原因,string的接口多达130多个,简直冗杂…所以学习过程中,我们只需要选取常用的,好用的来进行使用即可(有种垃圾堆里翻美食的感觉)

开始使用 string类 吧

首先不得不说的是由于历史原因,string的接口多达130多个,简直冗杂…

所以学习过程中,我们只需要选取常用的,好用的来进行使用即可(有种垃圾堆里翻美食的感觉)

1 继续学习

上一篇文章

上一篇文章我们给出了构造函数和一些成员函数的功能:

成员函数 作用
begin() 返回字符首位置 (迭代器常用 )
end() 返回字符结尾 (迭代器常用)
size(重点) 返回字符串有效字符长度
length 返回字符串有效字符长度
capacity 返回空间总大小
empty (重点) 检测字符串释放为空串,是返回true,否则返回false
clear (重点) 清空有效字符
reserve (重点) 为字符串预留空间
resize (重点) 将有效字符的个数该成n个,多出的空间用字符c填充

1.1 扩容机制

上一篇文章,我们看到了string的容量是比较模糊的,为什么是15???,它的扩容规则是什么???

接下来我们来探索一下string的扩容机制:

首先我们来写一个简单的测试程序:


#include<string>
#include<iostream>

using namespace std;

int main(){

  string s1 = "";

  for (int i = 0; i < 200; i++) {
    s1 += "c";
    //检查是否需要扩容 然后打印出来
    if (s1.size() == s1.capacity()) 
      cout << "string 的空间 :" << s1.capacity() << endl;
  }

  return 0;
}

来看看效果:

可以看出来VS2022 基本是以1.5 倍扩容。那全部的编译器都是1.5 倍吗???

再让我们来liunx中,用g++ 来试试哈。

所以不同编译器的扩容机制也不同,这就是历史的原因了。根据我们所学过的顺序表,我们可以很容易想到内部扩容机制是什么样子:

  1. 检查 size 是否 等于 capacity
  2. 如果相等 扩容
  3. 否则直接插入尾部。

1.2 string类对象的访问及遍历操作

函数名称 功能说明
operator[] (重点) 返回pos位置的字符,const string类对象调用
begin+ end begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rend rbegin获取一个字符的迭代器 + rend获取最后一个字符下一个位置的迭代器
范围for C++11支持更简洁的范围for的新遍历方式(底层是迭代器)

迭代器是C++新增的内容,功能类似指针,这里不细说,只将在string中如何使用。

首先看到迭代器(iterator)功能类似指针,那必须想到遍历的作用,对不对。接下来我们来看看迭代器的遍历好不好用。

注意不同类型的迭代器需要使用命名空间限定 这里是 string :: iterator

#include<string>
#include<iostream>

using namespace std;

int main() {

  string s1 = "I love you !";
  string::iterator it = s1.begin();
  while (it != s1.end())
  {
    cout << *it << " ";
    it++;
  }
  return 0;
}

看见这熟悉的结构,while()循环 *it it++是不是真的和指针一样。

再让我们看一下结果吧:

顺利的遍历了全部字符串。

接下来再来看一个好玩的,逆转迭代器reverse_iterator

#include<string>
#include<iostream>

using namespace std;

int main() {

  string s1 = "I love you !";

  string::reverse_iterator it = s1.rbegin();

  while (it != s1.rend())
  {
    cout << *it << " ";
    it++;
  }
  return 0;
}

仔细看,依然是 it++,而且起始位置也成为了rbegin() 结尾是rend() 是不是非常有意思。

来看效果:

成功逆转打印,very good!!!

同样也可以使用基于范围的for循环

for(auto it : s1){ } 即可完成遍历操作;

1.3 string类对象的修改操作

来给一波函数:

函数名称 功能说明
push_back 在字符串后尾插字符c
append 在字符串后追加一个字符串
operator+= (重点) 在字符串后追加字符串str
c_str(重点) 返回C格式字符串
find + npos(重点) 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr 在str中从pos位置开始,截取n个字符,然后将其返回

这里面其实有许多函数重载,不过常用的就那几个,有需求请自行查看:C++库

来初步使用一下插入函数:

#include<string>
#include<iostream>

using namespace std;

int main() {

  string s1 = "I love you !";

  s1.push_back('c');
  cout << "结尾插入字符 :" << s1 << endl;
  s1.append("forever");
  cout << "append 结尾插入字符串 :" << s1 << endl;
  s1 += "xxxxx";
  cout << "+= 结尾插入字符串 :" << s1 << endl;


  return 0;
}

非常顺利的插入了:

来看效果:

1.4 其他一些成员函数

函数 功能说明
operator+ 尽量少用,因为传值返回,导致深拷贝效率低
operator>> (重点) 输入运算符重载
operator<< (重点) 输出运算符重载
getline (重点) 获取一行字符串
relational operators (重点) 大小比较

这些我们以后再进行详细讲解。

2 实践解决问题:

家人们,上链接!!!!

1859 . 将句子排序

来看题目描述:

这个我们直接套用字符串操作模版即可:

这个非常好用的获取单词的办法,首先使用基于范围的for循环,然后遍历,只要不是空格,就插入到中间string类temp中,遇到空格,就把该单词存入数组中。非常好用!

然后这道题还要求我们完成排序,所以直接使用sort按要求排序即可。

最后删除结尾的数字,重新插入到s中即可。

bool compare(string a,string b){
    return a.back() < b.back();
}

class Solution {
public:
    string sortSentence(string s) {
        string temp = "";
        vector<string> res;
        s += " ";

        for(auto ch : s){
            if(ch == ' '){
                res.push_back(temp);
                temp.clear();
            }
            else{
                temp.push_back(ch);
            }
        }

        sort(res.begin(),res.end(),compare);
        s.clear();

        for(auto& it : res){
            it.pop_back();
            s += it + ' ';
        }   
        s.pop_back();
        return s;
    }
};

运行效果非常好:

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

相关文章
|
4天前
|
C语言 C++
【C++】string模拟实现(下)
本文档介绍了自定义`string`类的一些关键功能实现,包括`reserve()`用于内存管理,`push_back()`和`append()`添加字符或字符串,运算符`+=`的重载,以及`insert()`, `erase()`进行插入和删除操作。此外,还涵盖了`find()`查找函数,字符串的比较运算符重载,`substr()`获取子串,`clear()`清除内容,以及流插入和提取操作。常量`npos`用于表示未找到的标记。文档以代码示例和运行结果展示各功能的使用。
|
4天前
|
编译器 程序员 C语言
【C++】string模拟实现
这篇博客探讨了自定义实现C++ `string` 类的关键功能,包括构造、拷贝构造、赋值运算符重载及析构函数。作者强调了理解并实现这些功能对于面试的重要性。博客介绍了`string` 类的头文件`string.h`,其中定义了迭代器、基本成员函数如`swap()`、`size()`、`c_str()`等,并提到了深拷贝概念。此外,还展示了构造函数、析构函数和赋值运算符的实现,以及迭代器的定义与使用。博客还包括对C语言字符串函数的引用,以辅助读者理解实现细节。
|
4天前
|
编译器 C++
【C++】string类的使用④(字符串操作String operations )
这篇博客探讨了C++ STL中`std::string`的几个关键操作,如`c_str()`和`data()`,它们分别返回指向字符串的const char*指针,前者保证以&#39;\0&#39;结尾,后者不保证。`get_allocator()`返回内存分配器,通常不直接使用。`copy()`函数用于将字符串部分复制到字符数组,不添加&#39;\0&#39;。`find()`和`rfind()`用于向前和向后搜索子串或字符。`npos`是string类中的一个常量,表示找不到匹配项时的返回值。博客通过实例展示了这些函数的用法。
|
3天前
|
存储
数据存储之数组的特点,长度固定,适应变化需求,集合类特点是空间可变,ArrayList泛型,ArrayList<String> array = new ArrayList<String>()
数据存储之数组的特点,长度固定,适应变化需求,集合类特点是空间可变,ArrayList泛型,ArrayList<String> array = new ArrayList<String>()
|
4天前
|
C++
【C++】string类的使用④(常量成员Member constants)
C++ `std::string` 的 `find_first_of`, `find_last_of`, `find_first_not_of`, `find_last_not_of` 函数分别用于从不同方向查找目标字符或子串。它们都返回匹配位置,未找到则返回 `npos`。`substr` 用于提取子字符串,`compare` 则提供更灵活的字符串比较。`npos` 是一个表示最大值的常量,用于标记未找到匹配的情况。示例代码展示了这些函数的实际应用,如替换元音、分割路径、查找非字母字符等。
|
4天前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
9天前
|
C++
【C++】日期类Date(详解)②
- `-=`通过复用`+=`实现,`Date operator-(int day)`则通过创建副本并调用`-=`。 - 前置`++`和后置`++`同样使用重载,类似地,前置`--`和后置`--`也复用了`+=`和`-=1`。 - 比较运算符重载如`&gt;`, `==`, `&lt;`, `&lt;=`, `!=`,通常只需实现两个,其他可通过复合逻辑得出。 - `Date`减`Date`返回天数,通过迭代较小日期直到与较大日期相等,记录步数和符号。 ``` 这是236个字符的摘要,符合240字符以内的要求,涵盖了日期类中运算符重载的主要实现。
|
4天前
|
C++
C++】string类的使用③(修改器Modifiers)
这篇博客探讨了C++ STL中`string`类的修改器和非成员函数重载。文章介绍了`operator+=`用于在字符串末尾追加内容,并展示了不同重载形式。`append`函数提供了更多追加选项,包括子串、字符数组、单个字符等。`push_back`和`pop_back`分别用于在末尾添加和移除一个字符。`assign`用于替换字符串内容,而`insert`允许在任意位置插入字符串或字符。最后,`erase`函数用于删除字符串中的部分内容。每个函数都配以代码示例和说明。
|
4天前
|
安全 编译器 C++
【C++】string类的使用②(元素获取Element access)
```markdown 探索C++ `string`方法:`clear()`保持容量不变使字符串变空;`empty()`检查长度是否为0;C++11的`shrink_to_fit()`尝试减少容量。`operator[]`和`at()`安全访问元素,越界时`at()`抛异常。`back()`和`front()`分别访问首尾元素。了解这些,轻松操作字符串!💡 ```
|
4天前
|
存储 编译器 Linux
【C++】string类的使用②(容量接口Capacity )
这篇博客探讨了C++ STL中string的容量接口和元素访问方法。`size()`和`length()`函数等价,返回字符串的长度;`capacity()`提供已分配的字节数,可能大于长度;`max_size()`给出理论最大长度;`reserve()`预分配空间,不改变内容;`resize()`改变字符串长度,可指定填充字符。这些接口用于优化内存管理和适应字符串操作需求。