Middle
How do you work with the standard container library in C++?
sobes.tech AI
Answer from AI
#include <vector>
#include <list>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <algorithm> // For std::sort, std::find, etc.
#include <iostream>
int main() {
// std::vector - dynamic array
std::vector<int> vec = {1, 2, 3, 4, 5};
vec.push_back(6); // Add element to the end
std::cout << "Vector size: " << vec.size() << std::endl;
std::cout << "First element: " << vec[0] << std::endl;
// std::list - doubly linked list
std::list<int> lst = {10, 20, 30};
lst.push_front(5); // Add element to the front
lst.push_back(35); // Add element to the back
// Using iterators for traversal and modification:
auto it = lst.begin();
std::advance(it, 2); // Move 2 positions forward
lst.insert(it, 25); // Insert before current position
// Other operations:
lst.remove(10); // Remove by value
// std::map - associative array (key-value map, ordered by key)
std::map<std::string, int> counts;
counts["apple"] = 1;
counts["banana"] = 2;
counts["orange"] = 3;
std::cout << "Count of banana: " << counts["banana"] << std::endl;
if (counts.count("kiwi")) { // Check for key existence
std::cout << "Kiwi exists." << std::endl;
}
// std::unordered_map - associative array (hash map, unordered)
std::unordered_map<std::string, int> fast_counts;
fast_counts["apple"] = 1;
fast_counts["banana"] = 2;
// Access element:
std::cout << "Fast count of apple: " << fast_counts.at("apple") << std::endl;
// std::set - ordered set of unique elements
std::set<int> unique_numbers = {5, 2, 8, 2, 5};
std::cout << "Set elements:";
for (int num : unique_numbers) {
std::cout << " " << num; // Will print: 2 5 8 (ordered and unique)
}
std::cout << std::endl;
unique_numbers.insert(10); // Insert new element
// std::unordered_set - unordered set of unique elements (hash set)
std::unordered_set<int> fast_unique_numbers = {5, 2, 8, 2, 5};
std::cout << "Unordered set elements:";
for (int num : fast_unique_numbers) {
std::cout << " " << num; // Order may vary
}
std::cout << std::endl;
// Using algorithms from <algorithm>
std::vector<int> sort_vec = {3, 1, 4, 1, 5, 9};
std::sort(sort_vec.begin(), sort_vec.end()); // Sort vector
// Find element
auto find_it = std::find(sort_vec.begin(), sort_vec.end(), 4);
if (find_it != sort_vec.end()) {
std::cout << "Found 4 in sorted vector." << std::endl;
}
return 0;
}
I actively use standard containers, choosing the most suitable for the task based on requirements:
std::vector: For dynamic arrays with efficient random access and fast appending at the end. Inefficient for insertions and deletions in the middle.std::list: For doubly linked lists with efficient insertions and deletions at any position using iterators. Random access is inefficient.std::deque: For double-ended queues with efficient insertion and deletion at both the front and back.
For associative containers:
std::map: For ordered associative arrays with keys compared based on a comparison function. Operations like search, insert, and delete have logarithmic complexity O(log n).std::unordered_map: For unordered associative arrays based on hashing. Operations generally have constant average complexity O(1), but can degrade to linear O(n) in the worst case. Chosen when access speed is critical and order does not matter.
For sets:
std::set: For ordered sets of unique elements. Operations have logarithmic complexity O(log n).std::unordered_set: For unordered sets of unique elements based on hashing. Average complexity O(1).
I actively use iterators for accessing, traversing, and modifying containers. I apply algorithms from <algorithm> for standard operations like sorting, searching, filtering, and transforming elements, preferring them over manual loops when possible. I consider the complexity guarantees and memory ownership features of each container type when designing data structures in the application. I avoid copying containers unnecessarily, using references, pointers, or move semantics.