STL个人学习笔记

个人笔记

记录coding过程中的问题

mutiset的删除问题

众所周知,在set结构中删除元素可以使用.erase(x),但若是在multiset中,删除的是所有的x元素。
若仅想删除一个x元素,可以这么做:

unordered_multiset <char>::iterator pos = hash.find(s[i]);  
hash.erase(pos);

或直接使用unordered_map

accumulate

accumulate函数将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值
accumulate带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值

// 求和
vector<int> num;
accumulate(num.begin(), num.end(), 0)
// string
vector<string> s;
accumulate(s.begin(), s.end(), string(" "))

next_permutation

  STL提供了两个用来计算排列组合关系的算法,分别是next_permutation和prev_permutation。首先我们必须了解什么是“下一个”排列组合,什么是“前一个”排列组合。考虑三个字符所组成的序列{a,b,c}。

  这个序列有六个可能的排列组合:abc,acb,bac,bca,cab,cba。这些排列组合根据less-than操作符做字典顺序(lexicographical)的排序。即从小到大
  同样道理,那些固定b(序列中次小元素)而做的排列组合,在次序上将先于那些固定c而做的排列组合。以bac和bca为例,bac在bca之前,因为次序ac小于序列ca。面对bca,我们可以说其前一个排列组合是bac,而其后一个排列组合是cab。序列abc没有“前一个”排列组合,cba没有“后一个”排列组合。
  next_permutation()会取得[first,last)所标示之序列的下一个排列组合,如果没有下一个排列组合,便返回false;否则返回true。

用法:next_permutation(str.begin(),str.end());

lower_bound:

功能:查找非递减序列[first,last) 内第一个大于或等于某个元素的位置。

返回值:如果找到返回找到元素的地址否则返回last的地址。(这样不注意的话会越界,小心)

用法:int t=lower_bound(a+l,a+r,key)-a;(a是数组)。

upper_bound:

功能:查找非递减序列[first,last) 内第一个大于某个元素的位置。

返回值:如果找到返回找到元素的地址否则返回last的地址。(同样这样不注意的话会越界,小心)

用法:int t=upper_bound(a+l,a+r,key)-a;(a是数组)。或使用迭代器。

iota:

以 value 开始,按顺序递增填充的值的范围

int main()
{
	int arr[10];
	std::iota(arr, arr+10, 10);		// 10 - 19
	for (int i : arr) std::cout << i << ' ';
	std::cout << '\n';
	// 输出 10 11 12 13 14 15 16 17 18 19

	return 0;
}

max_element和min_element:

max_element返回最大值的地址。
*max_element返回最大值。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int a[]={4,2,3,8,5};
	int len=sizeof(a)/sizeof(int);
	cout<<*max_element(a,a+len)<<endl; //输出集合最大元素
	return 0;
}

advance和prev:

#include <iostream>     // std::cout
#include <iterator>     // std::advance
#include <vector>
using namespace std;
int main() {
    //创建一个 vector 容器
    vector<int> myvector{ 1,2,3,4 };
    //it为随机访问迭代器,其指向 myvector 容器中第一个元素
    vector<int>::iterator it = myvector.begin();
    //输出 it 迭代器指向的数据
    cout << "移动前的 *it = " << *it << endl;

    //借助 advance() 函数将 it 迭代器前进 2 个位置
    advance(it, 2);
    cout << "移动后的 *it = " << *it << endl;
    return 0;
}
移动前的 *it = 1
移动后的 *it = 3

通过程序的运行结果不难看出,advance() 函数没有任何返回值,其移动的是 it 迭代器本身。

这就产生一个问题,若我们不想移动 it 迭代器本身,而仅仅是想在 it 迭代器的基础上,得到一个移动指定位置的新迭代器,显然 advance() 函数是不合适的,这时就可以使用 C++ STL 标准库提供的另外 2 个函数,即 prev() 和 next() 函数。

其中,it 为源迭代器,其类型只能为双向迭代器或者随机访问迭代器;n 为指定新迭代器距离 it 的距离,默认值为 1。该函数会返回一个距离 it 迭代器 n 个元素的新迭代器。
注意,当 n 为正数时,其返回的迭代器将位于 it 左侧;反之,当 n 为负数时,其返回的迭代器位于 it 右侧。

#include <iostream>     // std::cout
#include <iterator>     // std::next
#include <list>         // std::list
using namespace std;
int main() {
    //创建并初始化一个 list 容器
    std::list<int> mylist{ 1,2,3,4,5 };
    std::list<int>::iterator it = mylist.end();
    //获取一个距离 it 迭代器 2 个元素的迭代器,由于 2 为正数,newit 位于 it 左侧
    auto newit = prev(it, 2);
    cout << "prev(it, 2) = " << *newit << endl;
   
    //n为负数,newit 位于 it 右侧
    it = mylist.begin();
    newit = prev(it, -2);
    cout << "prev(it, -2) = " << *newit;
    return 0;
}
prev(it, 2) = 4
prev(it, -2) = 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值