Data Structures
Arrays
1 | /* Built-in Array (fixed size) */ |
1 | /* vector */ |
String
http://www.cplusplus.com/reference/string/string/1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/* Initialization */
string s1;
string s2(s1);
string s2 = s1;
string s3("value");
string s3 = "value";
string s4(n, 'c');
// copy initialize: initialize a variable using =
// direct initialize: omit the =
/* string to number */
stoi(str); // to int
stof(str); // to float
stod(str); // to double
// atoi() is a C-way, not suggested
// from_chars() is introduced in C++17
/* number to string */
to_string(value); // value type: int, float, double, long, unsigned, etc.
string::npos // the value is -1
// when used as the value for a len, it means until the end of the string
// when used as a return value, it is usually used to indicate no matches
/* sub string */
s1.substr(pos = 0, len = npos); // note that the second parameter is the length of substring, not the ending position
/* find the index of another string/char */
s1.find(); // return npos if not found
/* cctype functions */
isalnum(ch);
isalpha(ch);
islower(ch);
isupper(ch);
isdigit(ch);
isblank(ch);
ispunct(ch);
tolower(ch);
toupper(ch);
/* split string(sentence) into vector of string(words) */
// reference: https://stackoverflow.com/a/5208977
string str("the sentence to split");
string buf; // a buffer string
stringstream ss(str); // insert the string into a stream
vector<string> tokens;
while (ss >> buf) // in this way, the delimiter is space
tokens.push_back(buf);
while (getline(ss, buf, ',')) // set other delimiter (e.g., ',') using getline
tokens.push_back(buf);
/* join the vector into a string */
// reference: https://stackoverflow.com/a/1430774
stringstream ss;
for (int i = 0; i < tokens.size(); ++i) {
if (i)
ss << " "; // or ',', or whatever delimiter
ss << tokens[i];
}
string s = ss.str();
Pair
1 |
|
Stack
1 |
|
Queue
Queue (Normal)
1 |
|
Priority Queue
1 |
|
Set
Hash Set
1 |
|
Set (Tree Set)
1 |
|
Map
Hash Map
1 |
|
Algorithms
Well, algorithm is not a separated concept from data structure, and some algorithms have been covered in the above section. Here I’ll just list some more.
Sort
For sorting algorithms, refer to my GitHub post. The post currently includes insertion sort, merge sort and quick sort.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//vector<int> v;
sort(v.begin(), v.end()); // sort the vector in ascending order
sort(v.begin(), v.end(), greater<int>()) // sort the vector in descending order
// What if we want to sort in custom order?
// E.g., vector<pair<int, int>> v1
// if we want to order the vector with the pairs' second value:
bool compareSecond(pair<int, int> p1, pair<int, int> p2) {
return p1.second < p2.second;
}
sort(v1.begin(), v1.end(), compareSecond);
// And how about priority queue?
// E.g., we have a pair, which contains a point (expressed as a pair) and its distance to origin.
// We want to build a min-heap with the distance.
typedef pair<pair<int, int>, int> point_dist;
class myCompare {
public:
bool operator()(point_dist pd1, point_dist pd2) {
return pd1.second > pd2.second;
}
}
priority_queue<point_dist, vector<point_dist>, myCompare> pq;
Binary Search
Given a sorted array, binary search could find the target with a time complexity of . Following is the basic template:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17int binarySearch(vector<int>& nums, int target) {
if (nums.empty())
return -1;
int left = 0, right = nums.size() - 1, mid;
while (left <= right) {
mid = left + (right - left) / 2; // avoid overflow
if (nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else // nums[mid] > target
right = mid - 1;
}
return -1;
}
The pointer left and right are used to control the search area.
If the middle value equals our target, then we just make it. If the middle value is less than the target, then it means that we should search the larger part. We need to move the left pointer to right. Otherwise, we need to move the right pointer to left if the middle value is greater.
Note that the calculation of mid is a bit counterintuitive. The purpose is to prevent the overflow caused by adding. Suppose that left is 1 and right is INT_MAX, then the adding will cause overflow and lead to errors. Therefore, it’s advised to use left + (right - left) / 2 instead.