目录
1、max_element()与min_element()【algorithm】
3、反向迭代器(reverse反转).rbegin(),.rend()
9、__lg函数(highbit函数取最高位的1,以二为底)
10、freopen(file stream open我觉得是这样)
2.默认安装first为主要关键字,second为次要关键字排序
1、max_element()与min_element()【algorithm】
时间复杂度:O(n),相当于一个for循环
返回值:指向对应类型的指针
格式:
max_element(首地址,尾地址)
1、查找字符串中最大的字符(vector同理,数组类似)
*max_element(str.begin(), str.end())
源代码:
template<typename _ForwardIterator, typename _Compare>
_ForwardIterator
__max_element(_ForwardIterator __first, _ForwardIterator __last,
_Compare __comp)
{
if (__first == __last) return __first;
_ForwardIterator __result = __first;
while (++__first != __last)
if (__comp(__result, __first))
__result = __first;
return __result;
}
/**
* @brief Return the maximum element in a range.
* @ingroup sorting_algorithms
* @param __first Start of range.
* @param __last End of range.
* @return Iterator referencing the first instance of the largest value.
*/
template<typename _ForwardIterator>
inline _ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last)
{
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_LessThanComparableConcept<
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return _GLIBCXX_STD_A::__max_element(__first, __last,
__gnu_cxx::__ops::__iter_less_iter());
}
/**
* @brief Return the maximum element in a range using comparison functor.
* @ingroup sorting_algorithms
* @param __first Start of range.
* @param __last End of range.
* @param __comp Comparison functor.
* @return Iterator referencing the first instance of the largest value
* according to __comp.
*/
template<typename _ForwardIterator, typename _Compare>
inline _ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last,
_Compare __comp)
{
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
typename iterator_traits<_ForwardIterator>::value_type,
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return _GLIBCXX_STD_A::__max_element(__first, __last,
__gnu_cxx::__ops::__iter_comp_iter(__comp));
}
_GLIBCXX_END_NAMESPACE_ALGO
} // namespace std
2、nth_element()【algorithm】
时间复杂度:O(n)
void
格式:
nth_element(v.begin(), v.begin() + 下标, v.end())
//可以把对应下标的数改为正确的数,按照升序排序。
证明:
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
vector<int> v;
v.push_back(5);
v.push_back(4);
v.push_back(3);
v.push_back(2);
v.push_back(1);
nth_element(v.begin(), v.begin() + 1, v.end());
cout << v[1] << '\n';//输出是2,如果升序排序的话2的下标是v[1]
cout << *max_element(v.begin(), v.end()) << '\n';//输出5
return 0;
}
3、反向迭代器(reverse反转).rbegin(),.rend()
sort(p.rbegin(), p.rend());//降序
sort(p.begin(), p.end());//升序
证明:
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
vector<int> v;
v.push_back(5);
v.push_back(4);
v.push_back(3);
v.push_back(2);
v.push_back(1);
sort(v.begin(), v.end());//输出1 2 3 4 5
for (int i = 0; i < v.size(); i++) {
cout << v[i] << ' ';
}
cout << '\n';
sort(v.rbegin(), v.rend());//输出5 4 3 2 1
for (int i = 0; i < v.size(); i++) {
cout << v[i] << ' ';
}
cout << '\n';
return 0;
}
4、构造函数(constructor)
为了便于给结构体变量赋值,我们常常使用构造函数来给结构体初始化。
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int from, to, cap, flow;
Edge(int from, int to, int cap, int flow) {
this->from = from;
this->to = to;
this->cap = cap;
this->flow = flow;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
Edge a = Edge(1, 2, 3, 4);
cout << a.from << ' ' << a.to << ' ' << a.cap << ' ' << a.flow << '\n';
return 0;
}
this关键字不可以省略,这样写起来更像一个函数。
也可以这样写。不过那个括号打的时候比较难受。
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int from, to, cap, flow;
Edge (int a, int b, int c, int d) : from(a), to(b), cap(c), flow(d) {}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
Edge a = Edge(1, 2, 3, 4);
cout << a.from << ' ' << a.to << ' ' << a.cap << ' ' << a.flow << '\n';
return 0;
}
然而事情并没有这么简单,如果只写一个的话,就无法开数组也无法开单单独开单个变量。
如:
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int from, to, cap, flow;
Edge(int from, int to, int cap, int flow) {
this->from = from;
this->to = to;
this->cap = cap;
this->flow = flow;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
Edge a;
return 0;
}
这时候需要写一个空的构造函数。
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int from, to, cap, flow;
Edge() {
}
Edge(int from, int to, int cap, int flow) {
this->from = from;
this->to = to;
this->cap = cap;
this->flow = flow;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
Edge a;
return 0;
}
5、__gcd()
在algorithm头文件里面的stl_algo.h头文件
源代码:
template<tpyename + 自定义的名字>
代表一种类型,在函数实现的时候替换为具体的int long long等。注意输入的时候要保持一致,否则无法编译。
template<typename _EuclideanRingElement>
_EuclideanRingElement
__gcd(_EuclideanRingElement __m, _EuclideanRingElement __n)
{
while (__n != 0)
{
_EuclideanRingElement __t = __m % __n;
__m = __n;
__n = __t;
}
return __m;
}
/// This is a helper function for the rotate algorithm.
和手写的效率相同:
int gcd(int a, int b) {
while (b > 0) {
int r = a % b;
a = b;
b = r;
}
return a;
}
6、友元函数与运算符重载
在使用优先队列的时候,使用友元函数可以自定义排序方式,写法如下:
struct test {
int a;
friend bool operator < (test a, test b) {
return a.a < b.a;//注意,这里的方向,和sort函数的cmp恰好相反,大于号是小顶堆,反之亦然
}
};
测试:
#include <bits/stdc++.h>
using namespace std;
struct test {
int a;
friend bool operator < (test a, test b) {
return a.a < b.a;
}
};
int main() {
test num[5];
priority_queue<test> q;
for (int i = 0; i < 5; i++) {
cin >> num[i].a;
q.push(num[i]);
}
while (!q.empty()) {
test c = q.top();
q.pop();
cout << c.a << ' ';
}
cout << '\n';
return 0;
}
/*
input 1 4 2 3 5
output 5 4 3 2 1
*/
7、unique去重函数。
在algorithm头文件内,标准命名空间。在sort之后用,非常实用!
#include <algorithm>
using namespace std;
#include <iostream>
int main() {
int a[] = {1, 1, 2, 2, 3};
int cnt = unique(a, a + 5) - a;//返回最后一个地址
for (int i = 0; i < 5; i++) {
cout << a[i] << ' ';//输出1 2 3 2 3
}
cout << '\n';
for (int i = 0; i < cnt; i++) {
cout << a[i] << ' ';//输出1 2 3
}
return 0;
}
时间复杂度o(n)
源代码:
/**
* @brief Remove consecutive values from a sequence using a predicate.
* @ingroup mutating_algorithms
* @param __first A forward iterator.
* @param __last A forward iterator.
* @param __binary_pred A binary predicate.
* @return An iterator designating the end of the resulting sequence.
*
* Removes all but the first element from each group of consecutive
* values for which @p __binary_pred returns true.
* unique() is stable, so the relative order of elements that are
* not removed is unchanged.
* Elements between the end of the resulting sequence and @p __last
* are still present, but their value is unspecified.
*/
template<typename _ForwardIterator, typename _BinaryPredicate>
inline _ForwardIterator
unique(_ForwardIterator __first, _ForwardIterator __last,
_BinaryPredicate __binary_pred)
{
// concept requirements
__glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
_ForwardIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
typename iterator_traits<_ForwardIterator>::value_type,
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return std::__unique(__first, __last,
__gnu_cxx::__ops::__iter_comp_iter(__binary_pred));
}
8、容器的遍历iterator迭代器
不同的版本的遍历的方法是不同的,这里笔者用的是devc++的gcc 4.9.2
实践出真知。
set集合默认是升序的。
第一题:{A} + {B}(set的遍历)
代码如下:
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int a, b;
while (cin >> a >> b) {
set<int> s;
set<int>::iterator it;//注意这个格式
int c;
while (a--) {
cin >> c;
s.insert(c);
}
while (b--) {
cin >> c;
s.insert(c);
}
for (it = s.begin(); it != s.end(); it++) {
if (it != s.begin()) {//注意迭代器不接受+-法,除了自加
cout << ' ';
}
cout << *it;。//类似指针
}
cout << '\n';
}
return 0;
}
第二题:map的遍历
map和set一样,map其实是一堆pair<key, value>,迭代器遍历的时候可以发现是安装键值的升序排列的,如果是字符串就是字典序。
证明:
#include <bits/stdc++.h>
using namespace std;
int main() {
map<string, string> mp;
mp["a"] = "c";
mp["c"] = "b";
mp["b"] = "a";
map<string, string>::iterator it;
for (it = mp.begin(); it != mp.end(); it++) {
cout << it->first << '\n';
}
return 0;
}
题目代码
#include <bits/stdc++.h>
using namespace std;
int main() {
map<string, string> m;
string t, s;
while (cin >> s) {
if (s == "XXXXXX") break;
t = s;
sort(s.begin(), s.end());
m[t] = s;
}
while (cin >> s) {
if (s == "XXXXXX") break;
int flag = 0;
sort(s.begin(), s.end());
map<string, string>::iterator it;
for (it = m.begin(); it != m.end(); it++) {
if (it->second == s) {
cout << it->first << '\n';
flag = 1;
}
}
if (!flag) cout << "NOT A VALID WORD\n";
cout << "******\n";
}
return 0;
}
9、__lg函数(highbit函数取最高位的1,以二为底)
类似如此,时间复杂度为O(1)
int findN(int n) {
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;// 整型一般是 32 位,上面我是假设 8 位。
return (n + 1) >> 1;
}
源代码:
__lg(unsigned long long __n)
{ return sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); }
注意这里和lowbit取出来的有些不同,这里取出来的是最高位的1是在第几位,是2的几次方。
10、freopen(file stream open我觉得是这样)
属于stdio.h
使用方法把in.txt文件放到exe文件的相同目录下。
#include <stdio.h>
#include <iostream>
using namespace std;
int main() {
int a,b;
freopen("in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取
freopen("out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中
while(cin>> a >> b) cout<< a+b <<endl; // 注意使用endl
fclose(stdin);//关闭文件
fclose(stdout);//关闭文件
return 0;
}
如果不能输入可能是txt文件是某些程序生成的,里面有特殊标记,比如EOF标记,建议删掉手动新建输入。如果要输出到窗口把stdout注释掉即可,文件不关闭问题不大。
11、string类的盘点。
.find():
时间复杂度:时间复杂度是O(n).
template
inline _InputIter find(_InputIter __first, _InputIter __last, const _Tp& __val, input_iterator_tag)
{
while (__first != __last && !(*__first == __val))
++__first;
return __first;
}
返回值:目标串的首字母的下标,如果找不到则返回-1,但是这里实际上是unsigned long long类型,所以显示的是1e18,
#include <bits/stdc++.h>
using namespace std;
int main() {
string s = "abc";
cout << (s.find("d")) << '\n';
cout << (s.find("d") == -1) << '\n';
cout << (s.find("a")) << '\n';
cout << (s.find("ab")) << '\n';
cout << (s.find("bc")) << '\n';
cout << (s.find("bcd")) << '\n';
/*
18446744073709551615
1
0
0
1
18446744073709551615
*/
}
参数:字符串,开始查找的下标(如果没有就是0)
题1:查找AB*BA,BA*AB其中*为任意
#include<iostream>
#include <string>
main() {
std::string s;
std::cin>>s;
if(s.find("AB")!=-1&&s.find("BA",s.find("AB")+2)!=-1||s.find("BA")!=-1&&s.find("AB",s.find("BA")+2)!=-1)std::cout<<"YES";
else std::cout<<"NO";
}
.insert()
时间复杂度:O(n),但是常数非常小,有时候有奇效。
/**
* @brief Insert one character.
* @param __p Iterator referencing position in string to insert at.
* @param __c The character to insert.
* @return Iterator referencing newly inserted char.
* @throw std::length_error If new length exceeds @c max_size().
*
* Inserts character @a __c at position referenced by @a __p.
* If adding character causes the length to exceed max_size(),
* length_error is thrown. If @a __p is beyond end of string,
* out_of_range is thrown. The value of the string doesn't
* change if an error is thrown.
*/
iterator
insert(iterator __p, _CharT __c)
{
_GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
const size_type __pos = __p - _M_ibegin();
_M_replace_aux(__pos, size_type(0), size_type(1), __c);
_M_rep()->_M_set_leaked();
return iterator(_M_data() + __pos);
}
运用:
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
string s = "abcdefgh";
s.insert(1, "abc");
cout << s << '\n';
return 0;
}
/*输出:
aabcbcdefgh
insert的第一个参数是首字母的下标
*/
12.pair的用法:
1.基本用法:
pair<T1, T2> p1; //创建一个空的pair对象(类似声明结构体),它的两个元素分别是T1和T2类型,采用值初始化。
pair<T1, T2> p1(v1, v2); //创建一个pair对象,它的两个元素分别是T1和T2类型,其中first成员初始化为v1,second成员初始化为v2。
make_pair(v1, v2); // 以v1和v2的值创建一个新的pair对象,其元素类型分别是v1和v2的类型。
p1 < p2; // 两个pair对象间的小于运算,其定义遵循字典次序
p1 == p2; // 如果两个对象的first和second依次相等
p1.first; // 返回对象p1中名为first的数据
p1.second; // 返回对象p1中名为second的数据
2.默认安装first为主要关键字,second为次要关键字排序
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
vector<pair<int, int> > v;
for (int i = 0; i < n; i++) {
int a, b;
cin >> a >> b;
v.push_back(make_pair(a, b));
}
sort(v.begin(), v.end());
for (int i = 0; i < n; i++) {
cout << v[i].first << ' ' << v[i].second << '\n';
}
return 0;
}
/*
input:
10
9 1
3 5
2 7
6 4
3 2
3 3
9 7
1 1
1 2
1 3
output:
1 1
1 2
1 3
2 7
3 2
3 3
3 5
6 4
9 1
9 7
*/