文章目录
前言
C++下标+【】、迭代器、范围for、迭代器对于其他容器都是通用的、迭代器可以更好的跟算法配合、rbegin和rend函数、const修饰的迭代器、力扣字符串相加等的介绍
遍历string可以使用下标+【】以及 迭代器遍历
一、 下标 + 【】
在字符数组中下标 + 【】本质上是指针的解引用。
但是在string类中 下标 + 【】本质上是函数的运算符重载 ----- operator[]
char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;
int main()
{
char ch[] = "hello world";
string s1("hello world");
cout << ch[0] << endl; // h 本质上是 *(ch + 0);
cout << s1[0] << endl; // h 本质上是 s1.operator[](0)
return 0;
}
遍历string类对象需要知道类对象的大小,所以首先来介绍的string类的一个成员函数 size。
size_t size() const;
size成员函数计算string类对象字符串的大小,不包括’\0’。
在size成员函数之前还有length,因为string比STL早出,string采用length,但是length又不适合说明树形结构。所以建议都使用size。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello world");
cout << s1.size() << endl; // 11 不包括'\0'
for (size_t i = 0; i < s1.size(); i++)
{
cout << s1[i] << ' ';
}
cout << endl;
return 0;
}
二、 迭代器
迭代器是一个像指针的类型,可以是指针,也可以不是。
若使用迭代器遍历string类对象,需要学习 begin 和 end 两个成员函数。
1.begin
iterator begin();
const_iterator begin() const;
返回值是一个类对象的第一个字符的迭代器。
int main()
{
string s1("hello world");
cout << *(s1.begin()) << endl; // h
return 0;
}
因为返回值是一个迭代器,返回值接收时使用迭代器类型。展开了std命名空间则使用string::iterator这种方式描述类型。
string::iterator it = s1.begin();
2. end
iterator end();
const_iterator end() const;
返回值是一个类对象的最后一个字符的下一个位置的迭代器。(左闭右开)
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello world");
cout << *(s1.end()) << endl; // error 越界报错
cout << *(s1.end() - 1) << endl; // d
return 0;
}
3. 使用迭代器遍历string类对象
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello world");
string::iterator it = s1.begin();
while (it != s1.end())
{
cout << *it << ' ';
++it;
}
cout << endl;
return 0;
}
三、范围for(语法糖)
范围for底层是通过迭代器实现的。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello csdn");
for (auto ch : s1) // 这里已知是char类型的数据,可以使用char,也可以用auto让编译器推导
{
cout << ch << ' ';
}
cout << endl;
return 0;
}
上述ch无法修改这个s1字符串,因为本质上是将s1中的字符依次拷贝给ch,所以ch改变了也无法影响s1。
int main()
{
string s1("hello csdn");
for (auto ch : s1)
{
ch++;
}
for (auto ch : s1)
{
cout << ch << ' ';
}
cout << endl;
return 0;
}
若要使用范围for改变s1字符串,可以使用引用,如下:
int main()
{
string s1("hello csdn");
for (auto& ch : s1)
{
ch++;
}
for (auto ch : s1) // 这里已知是char类型的数据,可以使用char,也可以用auto让编译器推导
{
cout << ch << ' ';
}
cout << endl;
return 0;
}
五、迭代器对于其他容器都是通用的
以 list 容器为例 (后面学)
#include <iostream>
#include <string>
#include <list>
using namespace std;
int main()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
list<int>::iterator lit = lt.begin();
while (lit != lt.end())
{
cout << *lit << ' ';
++lit;
}
cout << endl;
return 0;
}
六、迭代器可以更好地跟算法配合
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello csdn");
cout << "逆置前:";
for (auto& e : s1)
{
cout << e << ' ';
}
cout << endl;
reverse(s1.begin(), s1.end());
cout << "逆置后:";
for (auto& e : s1)
{
cout << e << ' ';
}
cout << endl;
return 0;
}
七、 rbegin 和 rend函数
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
与 begin 和 end 函数类似,但也有不同,返回值类型都是reverse_iterator
- rbegin 返回的指向类对象最后一个字符的迭代器。
- rend返回指向类对象第一个字符之前的迭代器。(左闭右开)
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1("hello csdn");
string::reverse_iterator it = s1.rbegin();
while (it != s1.rend())
{
cout << *it << ' ';
++it;
}
cout << endl;
return 0;
}
- 范围for只能顺序遍历。迭代器可以逆序等方式遍历。
八、 const 修饰的迭代器
#include <iostream>
#include <string>
using namespace std;
void Func(const string& s) // 直接传string类对象会调用拷贝构造,所以选择传引用,不希望s被改变时我们应该加const修饰
{
string::iterator it = s.begin();
while (it != s.end())
{
cout << *it << ' ';
++it;
}
cout << endl;
}
int main()
{
string s1("hello csdn");
Func(s1);
return 0;
}
使用const修饰的迭代器来接收返回值,就可以解决上述问题,如下:
void Func(const string& s)
{
string::const_iterator it = s.begin();
while (it != s.end())
{
cout << *it << ' ';
++it;
}
cout << endl;
}
九、力扣字符串相加
class Solution {
public:
string addStrings(string num1, string num2) {
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
int carry = 0;
string strRet;
while(end1 >= 0 || end2 >= 0)
{
int n1 = 0, n2 = 0;
if(end1 < 0)
n1 = 0;
else
n1 = num1[end1] - '0';
if(end2 < 0)
n2 = 0;
else
n2 = num2[end2] - '0';
int sum = n1 + n2 + carry;
strRet += sum % 10 + '0';
carry = sum / 10;
--end1;
--end2;
}
if(carry == 1)
strRet += '1';
reverse(strRet.begin(), strRet.end());
return strRet;
}
};
总结
C++下标+【】、迭代器、范围for、迭代器对于其他容器都是通用的、迭代器可以更好的跟算法配合、rbegin和rend函数、const修饰的迭代器、力扣字符串相加等的介绍