【C++/STL一些函数和类、方法】(更新至2023.1.15)(10931字)

目录

1、max_element()与min_element()【algorithm】

1、查找字符串中最大的字符(vector同理,数组类似)

2、nth_element()【algorithm】

3、反向迭代器(reverse反转).rbegin(),.rend()

4、构造函数(constructor)

5、__gcd()

6、友元函数与运算符重载

7、unique去重函数。

8、容器的遍历iterator迭代器

第一题:{A} + {B}(set的遍历)

第二题:map的遍历

9、__lg函数(highbit函数取最高位的1,以二为底)

10、freopen(file stream open我觉得是这样)

11、string类的盘点。

.find():

题1:查找AB*BA,BA*AB其中*为任意

.insert()

12.pair的用法:

1.基本用法:

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
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值