CPP 2
CPP 2
Programming in C++
Tony Wong (microtony)
2021-02-20
Programming in C++
Why C++?
● C++ shares similar syntax with many other programming languages
○ Java, Javascript, C#, Objective C, PHP etc..
Survey
How well do you know C++?
● I don’t know C++ at all
● I know about the basics and can write simple problems
● I know a lot about the language features, enough for
me to solve OI problems.
● I am an expert in C++. I have knowledge beyond those
needed in OI.
Programming in C++
#include <iostream>
Programming in C++
<bits/stdc++.h>
Programming in C++
#include <bits/stdc++.h>
using namespace std; This line is to “move” everything in
int main() {
the std namespace into the our
cout << "Hello, World!" << endl;
return 0; program.
} Pro:
● No need to type std:: prefix
Con:
● Program may not be forward
compatible
namespace
Programming in C++
#include <bits/stdc++.h>
Example without
int main() {
using namespace std;
std::cout << "Hello, World!" <<
std::endl;
return 0;
}
Programming in C++
#include <bits/stdc++.h>
using std::cout; Bring in specific symbols.
using std::endl;
int main() { This won’t have the forward
cout << "Hello, World!" << endl; compatibility issue.
return 0;
}
using declaration
Programming in C++
substr
Programming in C++
#include <bits/stdc++.h>
using namespace std;
int main() { This is the main program.
cout << "Hello, World!" << endl;
return 0;
} Note that the return type is int.
Main function
Programming in C++
Main function
Programming in C++
#include <bits/stdc++.h>
using namespace std;
int main() {
cout << "Hello, World!" << endl; Send “Hello, World!” and
return 0; line break to the output stream.
}
cout endl
Programming in C++
Arrays
We can use a character array to store strings.
C++ array
With the exception of const arrays, (e.g. const char s[])
modern C++ discourages the use of raw arrays.
The type and size of an array is fixed once declared.
array
Programming in C++
C++ array
Arrays can also be declared with initialization.
The size and type will be automatically determined.
Here, the type of a is array<int, 3>.
#include <bits/stdc++.h> Input Output
using namespace std;
15
array a{4, 8, 3};
int main() {
cout << a[0] + a[1] + a[2] << endl;
return 0;
}
Programming in C++
at
Programming in C++
vector
Programming in C++
int main() {
int n;
cin >> n;
vector<int> a; Input Output
Empty vector
for (int i = 0; i < n; ++i) {
int x; 6 27
cin >> x; 1 4 2 8 5 7
a.push_back(x);
}
int sum = 0;
for (int i = 0; i < n; ++i) {
sum += a[i];
}
cout << sum << endl;
return 0;
}
push_back
Programming in C++
vector assignment
We can replace the entire vector by assigning another vector to it.
operator=
Programming in C++
Reference declaration
Programming in C++
find distance
Programming in C++
Sort a vector
Use sort(first, last) to sort a vector in ascending order.
Use reverse(first, last) to reverse a vector.
sort reverse
Programming in C++
unique erase
Programming in C++
Comparing vectors
You can use equality operator == != to check if the vectors has the same length
and the same contents in the same order.
Comparison operators < <= >= > compare 2 vectors in lexicographical order.
vector comparison
Programming in C++
Internal storage
Vector always store the data in contiguous segment of memory.
When it is already full and you try to push one more element, it finds a larger
piece of memory elsewhere and move all the data there.
1
vector<int> a; Input Output
cout << a.capacity() << " ";
0 0
cout << a.data() << endl;
1 0x192400
for (int i = 1; i <= 6; ++i) { 1 2
2 0x196230
a.push_back(i);
1 2 3 4 0x192400
cout << a.capacity() << " ";
4 0x192400
cout << a.data() << endl;
8 0x196230
}
1 2 3 4 8 0x196230
capacity data
1 2 3 4 5
Programming in C++
Total cost for N push_back = N + (<2N) < 3N, and therefore is O(N)
We can say that push_back is amortized O(1)
push_back
Programming in C++
push_back
Programming in C++
2D vector
vector<vector<int>> a{{1, 2, 3}, {4}, {5, 6}}; Output
cout << a[0].size() << endl; 3
cout << a[1].size() << endl; 1
cout << a[2].size() << endl; 2
cout << a[2][0] << endl; 5
int n = 4; int n = 4;
int m = 5; int m = 5;
vector<vector<int>> a(n, vector<int>(m)); vector<vector<int>> a;
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) { vector<int> b;
cin >> a[i][j]; for (int j = 0; j < m; ++j) {
} int x;
} cin >> x;
b.push_back(x);
}
a.push_back(b);
}
Programming in C++
Remember move()?
vector<vector<int>> a; Output
vector<int> b{1, 2, 3}; 0x22400
cout << b.data() << endl; 0x26580
a.push_back(b); 3
cout << a[0].data() << endl;
cout << b.size() << endl;
Data is copied
vector<vector<int>> a; Output
vector<int> b{1, 2, 3}; 0xf82400
cout << b.data() << endl; 0xf82400
a.push_back(move(b)); 0
cout << a[0].data() << endl;
Not guaranteed
cout << b.size() << endl;
to be 0
std::move() is complicated.
No need to care about it in competitive programming.
data move
Programming in C++
vector<bool>
vector<bool> is a very special kind of vector.
Its implementation allows efficient storage of bools, 1 bit (vs 1 byte) for each bool.
Some vector functions cannot be used.
vector<bool>
Programming in C++
string
C++ strings are very easy to use.
You can concatenate strings together using the + operator.
Using string::iterator
You can get iterators from string to perform operations similar to vector.
Using string::iterator
You can get iterators from string to perform operations similar to vector.
string comparison
You can compare strings directly using comparison operators.
You can also use .compare(), which returns 0 when the strings are equal,
negative number when the left string is smaller, and positive otherwise.
compare
Programming in C++
Break
Please read M2102 problem statement
Programming in C++
Functions
Functions with return type should have a return statement.
Void functions can omit the return statement.
Function declaration
Programming in C++
Early Return
If you have a return statement at the end of a if block, no need to add else.
Pass by reference
Pass by reference makes the identifier refer to the same variable specified in
the argument. Therefore, the value can be changed inside the function.
void PassByValue(int a) { Output
a = 5; Value 1
}
1 5
void PassByReference(int& a) {
a = 5;
}
int main() { Refers to y
int x = 1;
int y = 2;
PassByValue(x);
PassByReference(y);
cout << x << " " << y << endl;
return 0;
}
Reference declaration
Programming in C++
struct
Use struct to declare data structures that can hold multiple data.
class
Programming in C++
Constructor
If you declare your own constructor, default constructor will not be
implicitly declared and defined.
struct Point { Output
double x, y; 1.73205 1
Point(double d, double r) {
x = d * cos(r);
y = d * sin(r);
}
};
int main() {
Point p(2, 0.5235988);
cout << p.x << " " << p.y << endl;
// Point q;
return 0; Compilation Error
}
Constructors
Default constructor
Programming in C++
Constructor
We can also use initializer list.
Member functions
struct Point { Output
double x, y;
Point(double d, double r) 1.73205 1
: x(d * cos(r)), y(d * sin(r)) {} 2
double DistanceToOrigin() { -1 1.73205
return sqrt(x * x + y * y);
}
void Rotate() {
swap(x, y);
x = -x;
}
};
int main() {
Point p(2, 0.5235988);
cout << p.x << " " << p.y << endl;
cout << p.DistanceToOrigin() << endl;
p.Rotate();
cout << p.x << " " << p.y << endl;
return 0;
} swap
Programming in C++
Overloading
struct Point { Output
double x, y;
Point Dot(double scalar) {
8.8 13.6
return {scalar * x, scalar * y}; 11.8
}
double Dot(const Point& p) {
return x * p.x + y * p.y;
}
};
int main() {
Point p{2.2, 3.4};
Point q = p.Dot(4.0);
cout << q.x << " " << q.y << endl;
Point r{1.5, 2.5};
double s = p.Dot(r);
cout << s << endl;
return 0;
}
Overload resolution
Programming in C++
Operator overloading
struct Point { Output
double x, y; 5.5 8.5
Point& operator*=(double scale) {
x *= scale;
y *= scale;
return *this;
}
};
int main() {
Point p{2.2, 3.4};
p *= 2.5;
cout << p.x << " " << p.y << endl;
return 0;
}
Operator overloading
Programming in C++
Operator overloading
struct Point { Output
double x, y;
Point& operator*=(double scale) {
5.5 8.5
x *= scale;
y *= scale;
return *this;
}
};
ostream& operator<<(ostream& os, const Point& p) {
os << p.x << " " << p.y;
return os;
}
int main() {
Point p{2.2, 3.4};
p *= 2.5; cout is a ostream
cout << p << endl;
return 0;
}
operator<<
See section Stream extraction and insertion
Programming in C++
Output a vector
ostream& operator<<(ostream& os, Output
const vector<int>& c) { 1 2 3 4 5
for (auto&& x : c) { 10 11 12
cout << x << " ";
}
cout << endl;
return os;
}
int main() {
vector<int> a{1, 2, 3, 4, 5};
vector<int> b{10, 11, 12};
cout << a << b;
return 0;
}
Programming in C++
Template
template<class T> Output
ostream& operator<<(ostream& os, 1 2 3 4 5
const vector<T>& c) { 1.2 3.4 5.6
for (auto&& x : c) {
cout << x << " ";
}
cout << endl;
return os;
}
int main() {
vector<int> a{1, 2, 3, 4, 5};
cout << a;
vector<double> b{1.2, 3.4, 5.6};
cout << b;
return 0;
}
Templates
Programming in C++
Output a 2D vector
template<class T> Output
ostream& operator<<(ostream& os, 11 12 13
const vector<T>& c) { 21 22
for (auto&& x : c) { 31 32 33
cout << x << " ";
}
cout << endl;
return os;
}
int main() {
vector<vector<int>> a{{11, 12, 13},
{21, 22},
{31, 32, 33}};
cout << a;
return 0;
}
Programming in C++
Pair
Pair can hold two values (first, second) of possibly different types.
Pairs can be compared. The first value will be compared first. If they are equal,
the second value will be compared.
pair
Programming in C++
Pair
Pair can be useful to return multiple values.
isupper islower
Programming in C++
Tuple
What about more values?
get(tuple)
Programming in C++
Input Output
3 4, July 1981
4, July 1981 22, December 1981
18, October 1982 18, October 1982
22, December 1981
Programming in C++
get
Programming in C++
find distance
Programming in C++
emplace_back
Programming in C++
Alternative way
const vector<string> kMonths = Input
{"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
3
int main() { 4, July 1981
int n; 18, October 1982
cin >> n; 22, December 1981
vector<tuple<int, int, int>> dates(n);
for (auto& date : dates) {
cin >> get<2>(date);
cin.get(); Output
string month_string;
cin >> month_string >> get<0>(date); 11
auto it = find(kMonths.begin(), kMonths.end(), month_string);
get<1>(date) = distance(kMonths.begin(), it);
}
cout << get<1>(dates[2]) << endl;
return 0;
}
Programming in C++
Even fancier
const vector<string> kMonths = Input
{"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
3
int main() { 4, July 1981
int n; 18, October 1982
cin >> n; 22, December 1981
vector<tuple<int, int, int>> dates(n);
for (auto& [year, month, day] : dates) {
cin >> day;
Structured binding declaration
cin.get(); Output
Must be auto
string month_string;
cin >> month_string >> year; 11
auto it = find(kMonths.begin(), kMonths.end(), month_string);
month = distance(kMonths.begin(), it);
}
cout << get<1>(dates[2]) << endl;
return 0;
}
Programming in C++
4 9.200000
&1.2
(120)
{4}
1,,2,,3,,4,,8,,7,,6,,5,,
5 4.625000
&1
(16
0){8}1,2,3,4,5,6,7,8,1,8,2,7
,{4}[1,8],[2,7],[3,6],(240)[4,5
],
Programming in C++
(120){4}1,,2,,3,,4,,8,,7,,6,,5,,
Programming in C++
(120){4}1,,2,,3,,4,,8,,7,,6,,5,,
(160){8}1,2,3,4,5,6,7,8,1,8,2,7,{4}[1,8],[2,7],[3,6],(240)[4,5],
160
8
4
240
Programming in C++
Solved?
C++17 C++20
Sadly, the 40 line program fails
to solve the task :(
because operator+ creates a
new string every time.
This will be “fixed” in C++20
where the intermediate value
will be moved using std::move.
accumulate
Programming in C++
Closing
Use a lot of library functions != Good programs
Programming in C++
Macros #define
#define
x first
y second dxxxxxe
#define pii pair<int,int>
#define ll long long
Some competitive #define
#define
pll pair<ll,ll>
pbb pair<bool,bool>
programmers use #define
#define
mp make_pair
pb push_back
#define pf push_front
macros to shorten #define popb pop_back
#define popf pop_front
their code. #define xmod (ll)(1e9+7) mxxxxxg
#define hmod 1286031825167LL
Exercises
01007 Packet Re-assembly
01009 Words
M1902 Zero and Scheduling Problem
M2001 Corona and WFH