【c/c++】刷算法題常用的函數,操作和容器彙總

刷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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章