目录
一、前言
二、什么是左闭右开?
✨ 如何理解开闭区间
✨如何理解左闭右开
✨ 左闭右开的好处
三、iterator迭代器中的---左闭右开原则
✨原则理解
✨应用
四、常考面试题
五、共勉
一、前言
想必大家在做 LeetCode 算法题的时候会经常看到有使用 STL库中的iterator迭代器 来处理各种问题,由于自己对 iterator迭代器中的 左闭右开原则不是很了解,查了资料在这里记录一下。
所以本文通过收集资料将其进行总结,主要介绍如何利用 iterator迭代器中的左闭右开原则 处理在算法练习或竞赛中遇到的问题。
二、什么是左闭右开?
✨ 如何理解开闭区间
开闭区间是一个数学概念,开区间使用符号小括号()
表示,闭区间使用符号中括号[]
表示,闭区间包含了两个端点,而开区间则不包含两个端点
示例:
一共四种情况:(a,b):区间范围内,不包含a和b[a,b]:区间范围内,包含a,也包含b(a,b]:区间范围内,不包含a,包含b[a,b):区间范围内,包含a,不包含b
✨如何理解左闭右开
左闭右开是一种区间表示方式,例如在整数上[3,6)表示3,4,5三个数,闭代表取值取到那个数,开代表取值取不到那个数。通常我们在程序中常听到的概念是左闭右开,也就是含左不含右,最常用的就是【C++】中的 iterator迭代器 它采取的就是左闭右开策略
✨ 左闭右开的好处
对于一个左闭右开区间[l,r)来说:
①:能表示单独一个数
若区间内只有一个数我们可以用像[1,2)表示1,注意[x,x]不符合数学上区间的定义(左区间比右区间大)
②:便于统计区间内个数
r 减 l 正好是区间内元素的个数,对于左闭右闭区间来说 r-l+1 才是区间内元素
③:便于表示空集
空集可以用[x,x)表示
④:便于切割区间
例如我们要在区间内找到一个切割点 x,并把 x 左边归为一个区间,x 和 x 右边归为一个区间则切割后的区间就可以用 [l,x) 和 [x,r) 表示
⑤:和数组下标相匹配
对于一个从0开始的长度为n的数组来说,[0,n)正好表示这个数组的所有下标,如果用闭区间则要用[0,n-1]来表示
三、iterator迭代器中的---左闭右开原则
✨原则理解
在 C++ 中,容器(如 string , vector , set , map 等)的迭代器都遵循左闭右开的原则。
也就是说,对于任何容器c
,c.begin()
返回的迭代器指向容器的第一个元素而 c.end()
返回的迭代器指向容器的“尾后”元素,也就是最后一个元素的下一个位置。所以, c.end()
不指向任何有效元素,不能解引用得到元素,通常只作为范围结束的标志。 例如,下面的代码是遍历一个 vector
的标准方法:
int main(){vector<int> v1 = { 1,2,3,4,5 };vector<int>::iterator it = v1.begin();while (it != v1.end()){cout << *it << " ";it++;}cout << endl;return 0;}
在这个例子中,v.begin()
返回的迭代器指向第一个元素 1
,v.end()
返回的迭代器指向尾后位置。我们一直迭代到 it
等于 v.end()
时停止,这时 it
已经不再指向任何有效元素。这就是左闭右开原则在 C++ 容器中的应用。
✨应用
根据上面原则的理解,我们可以得出结论:在任何容器中(如 string , vector , set , map 等) ,只要调用的函数应用了 iterator 迭代器,它就会遵循 ---- 左闭右开原则
下面我们将会以常见的 reverse 反转函数 在string容器中举例验证--- 左闭右开原则
根据 左闭右开原则,进行反转字符串
int main(){string s("hello !!");// 满足左闭右开原则reverse(s.begin(), s.begin() + 5);cout << s << endl;}
根据上面的图例,我们发现在 reverse(s.begin() , s.begin()+5 ) 中 ,满足左闭右开原则,[begin , begin+5) ,实际反转的 只有下标为 0 - 4 的 hello
四、常考面试题
题目:反转字符串中的单词
链接:反转字符串中的单词
class Solution {public: string reverseWords(string s) { size_t i = 0; size_t size = s.size(); while (i < size) { size_t bs = s.find(' ', i); if (bs != string::npos) { // 满足左闭右开的原则 reverse(s.begin() + i, s.begin() + bs); i = bs + 1; } else { reverse(s.begin()+ i, s.end()); break; } } return s; }};
五、共勉
以下就是我对 iterator迭代器 --- 左闭右开原则 的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++ vector 类的理解,请持续关注我哦!!!