刷OJ常用函數彙總
#include<iostream>
#include<algorithm>
#include<functional>
#include<vector>
#include<set>
#include<unordered_set>
//map中涉及pair,添加map頭文件的同時會自動添加pair頭文件
#include<map>
#include<unordered_map>
#include<stack>
#include<queue>
#include<deque>
#include<string>
#include<array>
#include<cstdlib>
#include<cctype>
#include<cmath>
//using namespace::some_name
using std::cout;
using std::cin;
using namespace std;
//結構體中的構造函數
//編譯器默認提供無參構造函數,自定義構造函數之後,則不提供無參構造
struct student {
int id;
char gender;
string name;
//自定義無參構造,初始化成員變量
student() { id = 0; gender = 'm'; name = ""; }
student(int _id, char _gender, string _name) {
this->id = _id;
this->gender = _gender;
this->name = _name;
}
};
struct teacher {
int id;
char gender;
string name;
//自定義無參構造,初始化成員變量
teacher() { id = 0; gender = 'm'; name = ""; }
teacher(int _id,char _gender,string _name):id(_id),gender(_gender),name(_name) {}
};
void f_constant() {
//#define name_of_constant value_of_constant
#define pi 3.14
//const修飾的常量 const type_name variable
const int ci = 12;
}
void f_bit_operation() {
//1.左移 <<
cout <<"左移: 1<<3 "<< (1<<3) << endl;
//2.右移 >>
cout << "右移: 16>>3 " << (16 >> 3) << endl;
//3.按位與 &
cout << "按位與:8 & 9 " << (8 & 9)<< endl;
//4.按位或 |
cout << "按位或:8 | 9 " << (8 | 9) << endl<< endl;
//5.位異或 ^
cout << "位異或:8 ^ 9 " <<(8 ^ 9)<< endl;
//6.位取反 ~
cout << "位取反:~8 " << (~8) << endl;
}
void f_char() {
char c1;
c1 = getchar();
putchar(c1);
}
//變長數組,可隨意調整數組長度,自動初始化爲0,false
void f_vector() {
//初始化
vector<int> v0(10);
vector<int> v1 = { 1,2,3,4 };
vector<int> v2(10, 2);
vector<int> v3;
vector<int> v4(v1);
//常用操作
v1.push_back(1);
v1.pop_back();
auto pb = v1.begin();
auto pe = v1.end();
v1.size();
v1.resize(100);
v1.clear();
v1.empty();
v1.insert(v1.begin()+2,10);
v1.erase(v1.begin() + 3);
v1.erase(v1.begin(),v1.begin()+3);
}
//內部自動有序不含重複元素(紅黑樹實現)
void f_set() {
//初始化
set<int> s0;
set<int> s1 = { 1,2,3,4,5 };
set<int> s2(s1);
//常用操作
auto pb = s0.begin();
auto pe = s0.end();
s0.insert(10);//set自動去除重複元素,且自動有序(multiset可重複,unordered_set無序)
//s0.erase(s0.find(10));
auto p_tmp = s0.find(10);//p_tmp是set<int>::iterator類型
cout << *p_tmp << endl;
s0.erase(p_tmp); //依據迭代器刪除單個元素
s0.erase(10); //依據元素的值刪除單個元素
s0.erase(s0.begin(), s0.end());//刪除迭代器指定的一串元素
s0.size();
s0.clear();
}
//map (紅黑樹實現)鍵唯一且有序,
//multimap 一個鍵對應多個值,
//unordered_map (散列實現)只映射不排序
void f_map() {
//初始化
map<char, int> mp;
mp['a'] = 0;
mp['b'] = 1;
mp['c'] = 2;
mp['d'] = 3;
//使用迭代器訪問map
for (auto pb = mp.begin(); pb != mp.end(); pb++) {
cout << pb->first << " " << pb->second << endl;
cout << (*pb).first << " " << (*pb).second << endl;
}
//使用鍵訪問map
cout << mp['a'] << " " << mp['b'] << mp['c'] << mp['d'] << endl;
//常用操作
auto it = mp.find('a');//find(key)返回鍵爲key的映射的迭代器
cout << it->first << " " << it->second << endl;
mp.erase(mp.find('a'));//erase(it),刪除迭代器指定的元素
mp.erase('b');//erase(key),刪除key指定的元素
mp.erase(mp.find('c'), mp.end());//erase(it1,it2),刪除[it1,it2)指定的元素
cout << mp.size() << endl;
mp.clear();
}
//後進先出,只能使用top()訪問棧頂元素
void f_stack() {
//初始化
stack<int> st;
for (int i = 0; i < 10; i++) {
st.push(i);
}
cout << st.top() << endl;//9
st.pop();
cout << st.top() << endl;//8
//常用操作 empty(),size()
}
void f_queue() {
//初始化
queue<int> q;
for (int i = 0; i < 10; i++) {
q.push(i); //壓入隊列
}
//常用操作
cout << q.front() << " " << q.back() << endl;//只訪問而不刪除
cout << q.size() << endl;
q.pop();//隊首元素出隊列
cout << q.empty() << endl;//是否爲空隊列
}
//雙端隊列,兩端都可插入和刪除
void f_deque() {
//初始化
deque<int> dq;
for (int i = 0; i < 10; i++) {
dq.push_back(i);
dq.push_front(i);
}
cout << dq.front() << " "<<dq.back() << endl;
dq.pop_front();
dq.pop_front();
cout << dq.size() << endl;
cout << dq.empty() << endl;
dq.clear();
for (auto pb = dq.begin(); pb != dq.end(); pb++) {
cout << *pb << endl;
}
}
//優先隊列,使用堆實現默認將當前隊列最大元素置於隊首的容器(大根堆)
/*
沒有front()和back()函數,只能通過top()函數訪問隊首元素,也就是優先級最高的元素(優先級可自定義)
*/
//結構體內部重載小於號(且只能重載小於號)實現自定義優先級
struct fruit {
string name;
int price;
friend bool operator<(fruit f1, fruit f2) {
return f1.price < f2.price;
}
};
//結構體外實現自定義優先級
struct animal {
string name;
int weight;
};
struct cmp {
bool operator()(animal a1, animal a2) {
return a1.weight > a2.weight;
}
};
void f_priority_queue() {
priority_queue<int> pq;//默認情況下爲大根堆
for (int i = 0; i < 10; i++) {
pq.push(i);
}
cout << pq.top();//9,默認是大根堆
//常用操作:push(),top(),pop(),empty(),size()
//自定義優先級
priority_queue<int, vector<int>, less<int> > pq1;//用<做比較,大根堆
priority_queue<long long, vector<long long>, greater<long long> >pq2;//用>作比較,小根堆
priority_queue<double, vector<double>, less<double> > pq3;//大根堆
priority_queue<char, vector<char>, less<char> > pq4;//大根堆
priority_queue<string, vector<string>, less<string> > pq5;//大根堆
//給結構體定義優先級
//結構體內部重載小於號(且只能重載小於號)
priority_queue<fruit> q1;//如果想以價格低的水果爲優先級高,那麼只需要把return中的小於號改爲大於號
fruit f1, f2, f3;
f1.name = "apple";
f1.price = 1;
f2.name = "banana";
f2.price = 2;
f3.name = "orange";
f3.price = 3;
q1.push(f1);
q1.push(f2);
q1.push(f3);
cout << q1.top().name << " " << q1.top().price << endl;//orange 3
//結構體外自定義cmp結構體實現自定義優先級
priority_queue<animal, vector<animal>, cmp> q2;
animal a1, a2, a3;
a1.name = "monkey";
a1.weight = 1;
a2.name = "snake";
a2.weight = 2;
a3.name = "horse";
a3.weight = 3;
q2.push(a1);
q2.push(a2);
q2.push(a3);
cout << q2.top().name << " " << q2.top().weight << endl;//monkey 1
}
//需要引入utility頭文件,但由於map中已經引入了utility,所以可以省略
//pair是將兩個元素綁在一起作爲一個合成元素
/*
pair具有以下兩個用途:
1.用以代替二元結構體及其構造函數,可以節省編碼時間
2.作爲map的鍵值對來進行插入
*/
void f_pair() {
//初始化
{
pair<string, int> p1;
pair<string, int> p2("this is a key of a pair", 1);
pair<string, int>("this is an anonymous pair", 2);//有點類似於匿名內部類
auto p3 = pair<string, int>("this is an anonymous pair", 2);
auto p4 = make_pair<string, int>("make_pair", 3);
pair<string, int> p5;
p5.first = "hello world!";
p5.second = 4;
cout << p5.first << " " << p5.second << endl;
}
//pair的比較
/*
先以first的大小作爲標準,僅當first相等時纔去判斷second的大小
*/
pair<int, int> p6(5, 10);
pair<int, int> p7(5, 15);
pair<int, int> p8(10, 5);
if (p6 < p8) cout << "p1<p8" << endl;//true
if (p6 <= p8) cout << "p1<=p8" << endl;//true
if (p6 < p7)cout << "p1<p7" << endl;//true
//作爲map的鍵值對元素
map<string, int> mp;
mp.insert(make_pair("make_pair",1));
mp.insert(pair<string, int>("pair key", 2));
pair<string, int> pair_tmp("another pair", 3);
mp.insert(pair_tmp);
}
void f_string() {
char c_type_str[] = "this is a c type string,using a char array";
cout << "c style string: " << c_type_str << endl;
cin.getline(c_type_str, sizeof(c_type_str) / sizeof(c_type_str[0]));
//convert a c style string to string
string cpp_type_str(c_type_str);
string cpp_type_str2 = c_type_str;
cout << "string cpp_type_str: " << cpp_type_str << endl;
//convert a string to c style string
const char* c_type_str2 = cpp_type_str.c_str();
c_type_str2 = "another c style string";
//讀取行
string str_getline;
getline(cin, str_getline);//從標準輸入中讀取整行並賦值給str
//訪問string中的單個元素
string str = "this is a demo string";
cout << str[2]; //用下標訪問str中的元素
cout << (*(str.begin()))<<" "<< (*(str.begin()+4)) << endl; //使用迭代器訪問str中的元素
cout<<str.length();
cout << str.size();
str.insert(3,"tmp_str");//insert(pos,string),在str[3]處插入tmp_str
string str_tmp = "this is a tmp string for insert";
//str.insert(it,it2,it3);it爲原字符串欲插入位置,it2,it3待插入字符串的首尾迭代器
//在str的指定迭代器位置,插入str_tmp迭代器指定的一段字符串
str.insert(str.begin(),str_tmp.begin(),str_tmp.begin()+4);
str.erase(str.begin() + 2);
str.erase(str.begin(), str.end() - 1);
str.erase(3,2);//從3號位置刪除2個字符
str.clear();
str.empty();
str.substr(0,5);//substr(pos,len);截取0號開始的5個字符子串
cout << string::npos << endl;
str = "thank you very much!";
str_tmp = "thank";
cout << ((str.find(str_tmp)) == (string::npos)) << endl;
//str.replace(pos,len,str2);把pos開始的長度爲len的子串替換爲str2
str.replace(10,4,str_tmp);
//str.replace(it1,it2,str2);把it1和it2之間的子串替換爲str2
str.replace(str.begin(),str.begin()+3,str_tmp);
}
//基本數據類型使用自定義cmp函數實現排序
bool cmp1(int a, int b) {
return a > b;//降序排序
}
struct book {
int num;
double price;
};
//自定義compare函數實現一級排序,按照book的價格降序排序
bool cmp2(book b1, book b2) {
return b1.price > b2.price;
}
//自定義compare函數實現二級排序,按照book的價格降序排序,編號升序
bool cmp3(book b1, book b2) {
return b1.price == b2.price ? b1.num<b2.num : b1.price>b2.price;
}
//自定義compare函數實現字符串字典序降序排序
bool cmp4(string str1, string str2) {
return str1 > str2;
}
//自定義compare函數實現按字符串長度降序
bool cmp5(string str1, string str2) {
return str1.length() > str2.length();
}
void f_algorithm() {
//0. max(),min(),abs(),swap()
int a = 1, b = -2;
cout << max(a, b) << " " << min(a, b) << endl;
cout << abs(b) << endl;
swap(a, b);
//1.排序,sort,默認升序
int ia[] = { 4,5,62,1,5,79,2 };
for (int i = 0; i < 7; i++) {
cout << ia[i];
}
sort(ia, ia + 7);
for (int i = 0; i < 7; i++) {
cout << ia[i];
}
//自定義compare函數
//1.基本數據類型使用自定義compare函數
sort(ia, ia + 7, cmp1);//自定義cmp1中使用>號實現降序排序(默認情況下升序排序)
for (int i = 0; i < 7; i++) {
cout << ia[i];
}
//2.1自定義結構體使用自定義compare函數實現一級排序
book arr_book[10];
for (int i = 0; i < 10; i++) {
arr_book[i].num = i * i;
arr_book[i].price = i / (arr_book[i].num);
}
sort(arr_book, arr_book + 10, cmp2);
//2.2自定義結構體使用自定義compare函數實現二級排序
sort(arr_book, arr_book + 10, cmp2);
//3.容器的排序
//vector舉例,實際上與數組相差不大,注意cmp函數的自定義即可
vector<int> vi;
for (int i = 0; i < 10; i++) {
vi.push_back(i);
}
sort(vi.begin(), vi.end(), cmp1);//cmp1中使用>號,實現降序排序
//string舉例
// 1.compare實現字典序降序
string arr_str[] = { "aaab","aab","ab" };
sort(arr_str, arr_str + 3, cmp4);
// 2.compare實現按字符串長度降序
sort(arr_str, arr_str + 3, cmp5);
//4.使用functional中提供的模板函數(需加入functional頭文件)
sort(ia, ia + 7, less<int>());
sort(ia, ia + 7, greater<int>());
//2.翻轉,reverse(it1,it2),翻轉[it1,it2)之間的元素
vector<int> v1 = { 0,1,2,3,4,5,6,7,8,9 };
for (auto it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
reverse(v1.begin(), v1.end());
for (auto it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
string str = "you know how much I like you";
reverse(str.begin(), str.end());
cout << str << endl;
//3.next_permutation(),給出一個序列在全排列中的下一個序列
//next_permutation(it1,it2)在到達全排列的最後一個時會返回false,使用do-while輸出最開始的排列123
int arr[] = { 1,2,3 };
do {
for (int i = 0; i < 3; i++) {
cout << arr[i];
}
} while (next_permutation(arr, arr + 3));
//4.fill(it1,it2,value)賦予[it1,it2)迭代器指定區間元素值value
int arr2[] = { 1,2,3,4,5 };
fill(arr2, arr2 + 5, 6666);
//5.lower_bound()和upper_bound(),用於有序數組和容器中
/*
lower_bound(first,last,val),Returns an iterator pointing to the first element
in the range [first, last) that is not less than (i.e. greater or equal to)
value, or last if no such element is found.
upper_bound(first,last,val),Returns an iterator pointing to the first element
in the range [first, last) that is greater than value, or last if no such
element is found.
*/
int arr_i[10] = { 1,2,2,3,4,4,5,5,5,5 };
int* lowerpos = lower_bound(arr_i, arr_i + 10, 2);
int* upperpos = upper_bound(arr_i, arr_i + 10, 5);
}
void f_cctype() {
//常用函數,
string str = "this is a random string with alphabetic character a-zA-Z and decimal digits:0123456789";
cout<<isalpha(str[10])<<endl; //是否爲字母
cout << isdigit(str[100]) << endl; //是否爲數字
cout << isalnum(str[0]) << endl; //是否爲字母或者數字
}
//常用的數學函數
void f_math() {
cout <<"abs(-1) " << abs(-1) << endl;
cout <<"floor(2.1) " << floor(2.1) << endl;
cout <<"ceil(2.1) "<< ceil(2.1) << endl;
cout << "pow(2.0,3.0) " << pow(2.0, 3.0) << endl;
cout << "sqrt(4.0)" << sqrt(4.0) << endl;
cout << "log(1) " << log(1) << endl;
cout << "round(4.4) " << round(4.4) << " round(4.5) " << round(4.5) << endl;
cout << "(int)(4.4 + 0.5) "<< (int)(4.4 + 0.5) <<" (int)(4.5 + 0.5) " << (int)(4.5 + 0.5) << endl;
}
//冒泡排序
void f_bubble_sort() {
const int sz = 10;
int a[sz] = { 9,3,1,5,2,4,8,7,10,6 };
for (int i = 0; i < sz-1; i++) {
for (int j = 0; j < sz - i - 1; j++) {
if (a[j] < a[j + 1]) {
swap(a[j],a[j+1]);
}
}
}
for (int tmp : a) {
cout << tmp << " ";
}
cout << endl;
}
//是否爲閏年
bool isleapyear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
//最大公約數(greatest common divisor)
//輾轉相除法,也叫歐幾里得算法
long long gcd(long long a,long long b) {
return b == 0 ? a : gcd(b, a % b);
}
//最小公倍數(lowest common multiple)
//最小公倍數 = a*b/最大公約數
long long lcm(long long a,long long b) {
return a * b / (gcd(a,b));
}
//進制轉換
//其它進制轉換爲十進制,str爲base進制下的字符串表示
/*
long strtol( const char *str, char **str_end, int base);需要使用'#include<cstdlib>'
丟棄所有空白字符(通過調用isspace()進行標識),直到找到第一個非空白字符爲止,然後使用盡
可能多的字符來形成有效的以n爲基(其中n = base)的整數表示並將其轉換爲一個整數值(十進制)。
*/
long xtod(string str,int base) {
char* tmp;
return strtol(str.c_str(), &tmp, 8);
}
//十進制轉換爲其它進制,digital爲10進制數,r爲需要轉換的目標進制,返回目標進制數
string dtox(int digital, int r) {
string result = "";
const char s[37] = "0123456789abcdefghijklmnopqrstuvwxyz";
if (digital == 0) {
return "0";
}
while (digital != 0) {
int tmp = digital % r;
result += s[tmp];
digital /= r;
}
reverse(result.begin(), result.end());
return result;
}
//string和其他基本數據類型的相互轉換
void f_convert() {
//string to int/long/long long/double
string str = "123456789";
int i = stoi(str);
long l = stol(str);
long long ll = stoll(str);
double db = stod(str);
//int/long/long long/double to string
string str_i = to_string(i);
string str_long = to_string(l);
string str_long_long = to_string(ll);
string str_db = to_string(db);
}
int main9() {
//f_bit_operation();
//f_math();
//f_bubble_sort();
//f_string();
return 0;
}