Vector in C++
A big limitation of static arrays in C++ is the fact that once the array is created, it has a fixed size.
The vector overcomes this limitation by having variable size and allowing for elements to be added or removed.
Creation:
You start a vector declaration by using the vector keyword, then writing the type of the elements inside <>, along with the name of the vector:
vector<string> sandwich;
This code creates an empty vector named sandwich where each item is a string.
Initialization I:
You can also initialize a vector at declaration by using the = operator with an opening bracket, end it with a closing bracket, and put a comma between each entry, like this:
vector<string> sandwich = {"peanut butter", "jelly", "bread"};
We created a vector named sandwich which consits of 3 items: "peanut butter", "jelly" and "bread".
Initialization II:
Another way of initializing a vector at declaration is by providing the number of elements and their initial value, like this:
vector<string> animals(5, "cat");
We created a vector named animals which consits of 5 "cat" items.
Assignment
Follow the Coding Tutorial and let's create some vectors!
Hint
Look at the examples above if you get stuck.
Introduction
In this lesson, we will explore the concept of vectors in C++. Vectors are a part of the Standard Template Library (STL) and provide a dynamic array functionality. Unlike static arrays, vectors can change their size dynamically, which makes them extremely useful in various programming scenarios.
Vectors are particularly useful in situations where the number of elements is not known beforehand or can change during the execution of the program. They are widely used in competitive programming, game development, and any application that requires dynamic data storage.
Understanding the Basics
Before diving into the advanced features of vectors, it's essential to understand their basic structure and usage. A vector in C++ is a sequence container that encapsulates dynamic size arrays. Here are some fundamental concepts:
- Declaration: You declare a vector using the
vectorkeyword followed by the type of elements it will store. - Initialization: Vectors can be initialized in multiple ways, either by specifying the elements directly or by defining the size and initial value.
- Accessing Elements: Elements in a vector can be accessed using the index operator
[]or theat()method.
Understanding these basics is crucial before moving on to more complex operations like insertion, deletion, and iteration.
Main Concepts
Let's delve deeper into some key concepts and techniques related to vectors:
- Adding Elements: You can add elements to a vector using the
push_back()method. - Removing Elements: Elements can be removed using the
pop_back()method or theerase()method for specific positions. - Size and Capacity: The
size()method returns the number of elements in the vector, while thecapacity()method returns the size of the storage space currently allocated.
Here is an example demonstrating these concepts:
#include <iostream>
#include <vector>
int main() {
// Creating a vector of integers
std::vector<int> numbers;
// Adding elements to the vector
numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);
// Accessing elements
std::cout << "First element: " << numbers[0] << std::endl;
// Removing the last element
numbers.pop_back();
// Size and capacity
std::cout << "Size: " << numbers.size() << std::endl;
std::cout << "Capacity: " << numbers.capacity() << std::endl;
return 0;
}
Examples and Use Cases
Let's look at some examples to understand how vectors can be used in different contexts:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// Example 1: Storing and sorting student grades
std::vector<int> grades = {85, 92, 78, 90, 88};
std::sort(grades.begin(), grades.end());
std::cout << "Sorted grades: ";
for (int grade : grades) {
std::cout << grade << " ";
}
std::cout << std::endl;
// Example 2: Dynamic list of names
std::vector<std::string> names;
names.push_back("Alice");
names.push_back("Bob");
names.push_back("Charlie");
std::cout << "Names: ";
for (const std::string& name : names) {
std::cout << name << " ";
}
std::cout << std::endl;
return 0;
}
In the first example, we store and sort student grades. In the second example, we dynamically manage a list of names.
Common Pitfalls and Best Practices
When working with vectors, there are some common pitfalls to avoid and best practices to follow:
- Avoid Excessive Copying: Use references or pointers to avoid unnecessary copying of large vectors.
- Reserve Space: If you know the number of elements in advance, use the
reserve()method to allocate memory upfront and avoid multiple reallocations. - Use Iterators: Prefer using iterators for traversing vectors as they provide better abstraction and flexibility.
Advanced Techniques
Once you are comfortable with the basics, you can explore advanced techniques such as:
- Using Emplace: The
emplace_back()method constructs elements in place, which can be more efficient thanpush_back(). - Custom Allocators: You can define custom memory allocators for vectors to optimize performance for specific use cases.
Here is an example using emplace_back():
#include <iostream>
#include <vector>
class Point {
public:
int x, y;
Point(int x, int y) : x(x), y(y) {}
};
int main() {
std::vector<Point> points;
points.emplace_back(1, 2);
points.emplace_back(3, 4);
for (const Point& point : points) {
std::cout << "Point(" << point.x << ", " << point.y << ")" << std::endl;
}
return 0;
}
Debugging and Testing
Debugging and testing are crucial aspects of working with vectors:
- Debugging: Use debugging tools to step through your code and inspect the state of your vectors.
- Testing: Write test cases to verify the correctness of your vector operations. Use frameworks like Google Test for comprehensive testing.
Here is an example of a simple test case:
#include <iostream>
#include <vector>
#include <cassert>
void test_vector() {
std::vector<int> vec = {1, 2, 3};
assert(vec.size() == 3);
assert(vec[0] == 1);
assert(vec[1] == 2);
assert(vec[2] == 3);
vec.push_back(4);
assert(vec.size() == 4);
assert(vec[3] == 4);
}
int main() {
test_vector();
std::cout << "All tests passed!" << std::endl;
return 0;
}
Thinking and Problem-Solving Tips
When working with vectors, consider the following strategies:
- Break Down Problems: Divide complex problems into smaller, manageable parts and solve them step-by-step.
- Practice: Regularly practice coding problems involving vectors to improve your skills and understanding.
- Explore Documentation: Refer to the official C++ documentation and resources to learn more about vector functionalities and best practices.
Conclusion
In this lesson, we covered the basics and advanced concepts of vectors in C++. Vectors are a powerful and flexible tool for dynamic data storage, and mastering them is essential for efficient programming. Keep practicing and exploring further applications to enhance your skills.
Additional Resources
For further reading and practice, consider the following resources: