C++下标+【】、迭代器、范围for、迭代器对于其他容器都是通用的、迭代器可以更好的跟算法配合、rbegin和rend函数、const修饰的迭代器、力扣字符串相加等的介绍


前言

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修饰的迭代器、力扣字符串相加等的介绍

  • 14
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值