[STL] Danh sách các hàm Algorithm thường dùng trong C++
Việc tìm kiếm, sắp xếp, đếm số lần xuất hiện, xóa phần tử không mong muốn, tính tổng, min và max của các phần tử trong một container là những thao tác phổ biến và quan trọng. Để thực hiện những công việc này một cách hiệu quả, C++ đã cung cấp thư viện STL (Standard Template Library) với nhiều hàm Algorithm hữu ích.
Trong bài viết này, mình sẽ tìm hiểu về các hàm Algorithm thường được sử dụng trong STL của C++, cùng với ví dụ minh họa cụ thể để hiểu rõ cách sử dụng và ứng dụng của từng hàm.
Các hàm Algorithm thường dùng trong C++
Hàm tìm kiếm
std::find():
Tìm kiếm một phần tử cụ thể trong một dãy và trả về iterator đến phần tử đó nếu tìm thấy, hoặc iterator cuối nếu không tìm thấy.
Ví dụ:
Bài viết này được đăng tại [free tuts .net]
#include <iostream> #include <vector> #include <algorithm> //Bài đăng tại freetuts.net int main() { std::vector<int> numbers = {1, 2, 3, 4, 5}; auto it = std::find(numbers.begin(), numbers.end(), 3); if (it != numbers.end()) { std::cout << "Phan tu 3 duoc tim thay tai vi tri: " << std::distance(numbers.begin(), it) << std::endl; } else { std::cout << "Khong tim thay phan tu 3 trong vector." << std::endl; } return 0; }
std::find_if():
Tìm kiếm phần tử đầu tiên trong một dãy thỏa mãn điều kiện được xác định bởi một hàm hoặc một predicate và trả về iterator đến phần tử đó.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> bool isOdd(int n) { return n % 2 != 0; } //Bài đăng tại freetuts.net int main() { std::vector<int> numbers = {1, 2, 3, 4, 5}; auto it = std::find_if(numbers.begin(), numbers.end(), isOdd); if (it != numbers.end()) { std::cout << "Phan tu le dau tien trong vector la: " << *it << std::endl; } else { std::cout << "Khong tim thay phan tu le trong vector." << std::endl; } return 0; }
std::find_if_not():
Tìm kiếm phần tử đầu tiên trong một dãy không thỏa mãn điều kiện được xác định bởi một hàm hoặc một predicate và trả về iterator đến phần tử đó.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> bool isOdd(int n) { return n % 2 != 0; } //Bài đăng tại freetuts.net int main() { std::vector<int> numbers = {2, 4, 6, 7, 8}; auto it = std::find_if_not(numbers.begin(), numbers.end(), isOdd); if (it != numbers.end()) { std::cout << "Phan tu dau tien trong vector la: " << *it << std::endl; } else { std::cout << "Khong tim thay phan tu nao thoa man dieu kien." << std::endl; } return 0; }
Hàm so sánh
std::equal():
So sánh hai dãy có bằng nhau hay không. Trả về true nếu các phần tử trong hai dãy là bằng nhau và false ngược lại.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> //Bài đăng tại freetuts.net int main() { std::vector<int> v1 = {1, 2, 3, 4, 5}; std::vector<int> v2 = {1, 2, 3, 4, 5}; bool result = std::equal(v1.begin(), v1.end(), v2.begin()); std::cout << "v1 va v2 co bang nhau khong? " << std::boolalpha << result << std::endl; return 0; }
std::lexicographical_compare():
So sánh hai dãy theo thứ tự từ điển. Trả về true
nếu dãy thứ nhất nhỏ hơn dãy thứ hai và false
ngược lại.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> //Bài đăng tại freetuts.net int main() { std::vector<int> v1 = {1, 2, 3}; std::vector<int> v2 = {1, 2, 4}; bool result = std::lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end()); std::cout << "v1 < v2 lexicographically? " << std::boolalpha << result << std::endl; return 0; }
std::equal_range():
Tìm phạm vi của các phần tử bằng nhau trong một dãy đã được sắp xếp.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {1, 2, 2, 3, 3, 3, 4, 5}; auto range = std::equal_range(v.begin(), v.end(), 3); //Bài đăng tại freetuts.net std::cout << "Pham vi cac phan tu bang 3: [" << std::distance(v.begin(), range.first) << ", " << std::distance(v.begin(), range.second) << ")" << std::endl; return 0; }
Hàm sắp xếp
std::sort():
Sắp xếp các phần tử trong một dãy theo thứ tự tăng dần.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> //Bài đăng tại freetuts.net int main() { std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6}; std::sort(v.begin(), v.end()); std::cout << "Danh sach sau khi sap xep: "; for (int num : v) { std::cout << num << " "; } std::cout << std::endl; return 0; }
std::stable_sort():
Sắp xếp các phần tử trong một dãy theo thứ tự tăng dần, bảo toàn thứ tự của các phần tử có giá trị bằng nhau.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> //Bài đăng tại freetuts.net int main() { std::vector<std::pair<int, char>> v = {{3, 'c'}, {1, 'a'}, {4, 'd'}, {1, 'b'}, {5, 'e'}}; std::stable_sort(v.begin(), v.end()); std::cout << "Danh sach sau khi sap xep: "; for (auto& pair : v) { std::cout << "(" << pair.first << ", " << pair.second << ") "; } std::cout << std::endl; return 0; }
std::partial_sort():
Sắp xếp một phần của dãy theo thứ tự tăng dần.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> //Bài đăng tại freetuts.net int main() { std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6}; std::partial_sort(v.begin(), v.begin() + 4, v.end()); std::cout << "4 phan tu dau sau khi sap xep: "; for (int i = 0; i < 4; ++i) { std::cout << v[i] << " "; } std::cout << std::endl; return 0; }
Hàm đếm
std::count():
Đếm số lần xuất hiện của một giá trị cụ thể trong một dãy.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> //Bài đăng tại freetuts.net int main() { std::vector<int> v = {1, 2, 2, 3, 2, 4, 5, 2}; int count = std::count(v.begin(), v.end(), 2); std::cout << "So lan xuat hien cua gia tri 2 la: " << count << std::endl; return 0; }
std::count_if():
Đếm số lượng phần tử trong một dãy thỏa mãn một điều kiện được xác định bởi một hàm hoặc một predicate.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> bool isEven(int n) { return n % 2 == 0; } //Bài đăng tại freetuts.net int main() { std::vector<int> v = {1, 2, 3, 4, 5}; int count = std::count_if(v.begin(), v.end(), isEven); std::cout << "So luong so chan trong vector la: " << count << std::endl; return 0; }
std::count_if_not():
Đếm số lượng phần tử trong một dãy không thỏa mãn một điều kiện được xác định bởi một hàm hoặc một predicate.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> bool isEven(int n) { return n % 2 == 0; } //Bài đăng tại freetuts.net int main() { std::vector<int> v = {1, 2, 3, 4, 5}; int count = std::count_if_not(v.begin(), v.end(), isEven); std::cout << "So luong so le trong vector la: " << count << std::endl; return 0; }
Hàm xóa
std::remove():
Di chuyển tất cả các phần tử bằng với giá trị được chỉ định ra khỏi dãy, và trả về iterator đến phần tử cuối cùng trong dãy sau khi xóa.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {1, 2, 2, 3, 2, 4, 5, 2}; auto it = std::remove(v.begin(), v.end(), 2); v.erase(it, v.end()); //Bài đăng tại freetuts.net std::cout << "Danh sach sau khi xoa cac phan tu 2: "; for (int num : v) { std::cout << num << " "; } std::cout << std::endl; return 0; }
std::remove_if():
Di chuyển tất cả các phần tử thỏa mãn điều kiện được xác định bởi một hàm hoặc một predicate ra khỏi dãy, và trả về iterator đến phần tử cuối cùng trong dãy sau khi xóa.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> bool isEven(int n) { return n % 2 == 0; } int main() { std::vector<int> v = {1, 2, 3, 4, 5}; auto it = std::remove_if(v.begin(), v.end(), isEven); v.erase(it, v.end()); //Bài đăng tại freetuts.net std::cout << "Danh sach sau khi xoa cac so chan: "; for (int num : v) { std::cout << num << " "; } std::cout << std::endl; return 0; }
std::remove_copy():
Sao chép tất cả các phần tử không bằng với giá trị được chỉ định vào một dãy mới.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {1, 2, 2, 3, 2, 4, 5, 2}; std::vector<int> v2(v.size()); //Bài đăng tại freetuts.net auto it = std::remove_copy(v.begin(), v.end(), v2.begin(), 2); v2.erase(it, v2.end()); std::cout << "Danh sach sau khi sao chep va xoa cac phan tu 2: "; for (int num : v2) { std::cout << num << " "; } std::cout << std::endl; return 0; }
Hàm thay thế
std::replace():
Thay thế tất cả các phần tử bằng giá trị cũ thành giá trị mới trong một dãy.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {1, 2, 2, 3, 2, 4, 5, 2}; std::replace(v.begin(), v.end(), 2, 6); //Bài đăng tại freetuts.net std::cout << "Danh sach sau khi thay the cac phan tu 2 bang 6: "; for (int num : v) { std::cout << num << " "; } std::cout << std::endl; return 0; }
std::replace_if():
Thay thế tất cả các phần tử thỏa mãn điều kiện được xác định bởi một hàm hoặc một predicate thành một giá trị mới.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> bool isEven(int n) { return n % 2 == 0; } int main() { std::vector<int> v = {1, 2, 3, 4, 5}; std::replace_if(v.begin(), v.end(), isEven, 0); //Bài đăng tại freetuts.net std::cout << "Danh sach sau khi thay the cac so chan bang 0: "; for (int num : v) { std::cout << num << " "; } std::cout << std::endl; return 0; }
std::replace_copy():
Sao chép tất cả các phần tử và thay thế các phần tử bằng giá trị cũ thành giá trị mới trong một dãy mới.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {1, 2, 2, 3, 2, 4, 5, 2}; std::vector<int> v2(v.size()); //Bài đăng tại freetuts.net std::replace_copy(v.begin(), v.end(), v2.begin(), 2, 6); std::cout << "Danh sach sau khi sao chep va thay the cac phan tu 2 bang 6: "; for (int num : v2) { std::cout << num << " "; } std::cout << std::endl; return 0; }
Hàm trộn
std::merge():
Trộn hai dãy đã sắp xếp thành một dãy mới đã sắp xếp.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v1 = {1, 3, 5, 7}; std::vector<int> v2 = {2, 4, 6, 8}; //Bài đăng tại freetuts.net std::vector<int> result(v1.size() + v2.size()); std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), result.begin()); std::cout << "Danh sach sau khi tron hai vector: "; for (int num : result) { std::cout << num << " "; } std::cout << std::endl; return 0; }
std::inplace_merge():
Trộn hai phần của một dãy đã sắp xếp thành một dãy đã sắp xếp.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {2, 4, 1, 3, 5, 7}; //Bài đăng tại freetuts.net std::inplace_merge(v.begin(), v.begin() + 2, v.end()); std::cout << "Danh sach sau khi tron hai phan: "; for (int num : v) { std::cout << num << " "; } std::cout << std::endl; return 0; }
std::set_union():
Trộn hai dãy đã sắp xếp thành một dãy mới chứa tất cả các phần tử không trùng lặp.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v1 = {1, 2, 3, 4, 5}; std::vector<int> v2 = {3, 4, 5, 6, 7}; std::vector<int> result(v1.size() + v2.size()); //Bài đăng tại freetuts.net std::set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), result.begin()); std::cout << "Danh sach sau khi tron hai vector va loai bo phan tu trung lap: "; for (int num : result) { std::cout << num << " "; } std::cout << std::endl; return 0; }
Hàm tính tổng, min, max
std::accumulate():
Tính tổng các phần tử trong một dãy.
Ví dụ:
#include <iostream> #include <vector> #include <numeric> int main() { std::vector<int> v = {1, 2, 3, 4, 5}; //Bài đăng tại freetuts.net int sum = std::accumulate(v.begin(), v.end(), 0); std::cout << "Tong cac phan tu trong vector: " << sum << std::endl; return 0; }
std::min_element()
và std::max_element():
Tìm phần tử nhỏ nhất và lớn nhất trong một dãy.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6}; auto min_it = std::min_element(v.begin(), v.end()); //Bài đăng tại freetuts.net auto max_it = std::max_element(v.begin(), v.end()); std::cout << "Gia tri nho nhat: " << *min_it << std::endl; std::cout << "Gia tri lon nhat: " << *max_it << std::endl; return 0; }
std::minmax_element():
Tìm phần tử nhỏ nhất và lớn nhất trong một dãy cùng một lúc.
Ví dụ:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6}; //Bài đăng tại freetuts.net auto minmax = std::minmax_element(v.begin(), v.end()); std::cout << "Gia tri nho nhat: " << *minmax.first << std::endl; std::cout << "Gia tri lon nhat: " << *minmax.second << std::endl; return 0; }
Đây là một số hàm Algorithm thường được sử dụng trong STL của C++. Các hàm này cung cấp các phương tiện mạnh mẽ để thao tác và xử lý dữ liệu một cách dễ dàng và hiệu quả.
Ví dụ thực hành của các hàm Algorithm trong C++
Ví dụ về tìm kiếm phần tử
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {1, 2, 3, 4, 5}; //Bài đăng tại freetuts.net int target = 3; auto it = std::find(v.begin(), v.end(), target); if (it != v.end()) { std::cout << "Phan tu " << target << " duoc tim thay tai vi tri " << std::distance(v.begin(), it) << std::endl; } else { std::cout << "Phan tu " << target << " khong tim thay trong vector" << std::endl; } return 0; }
Kết quả:
Ví dụ về sắp xếp dãy số
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6}; std::sort(v.begin(), v.end()); //Bài đăng tại freetuts.net std::cout << "Danh sach sau khi sap xep: "; for (int num : v) { std::cout << num << " "; } std::cout << std::endl; return 0; }
Kết quả:
Ví dụ về đếm số lần xuất hiện của một phần tử
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {1, 2, 2, 3, 2, 4, 5, 2}; //Bài đăng tại freetuts.net int target = 2; int count = std::count(v.begin(), v.end(), target); std::cout << "So lan xuat hien cua phan tu " << target << " la: " << count << std::endl; return 0; }
Kết quả:
Ví dụ về xóa các phần tử không mong muốn
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = {1, 2, 3, 4, 5}; int target = 3; auto it = std::remove(v.begin(), v.end(), target); v.erase(it, v.end()); std::cout << "Danh sach sau khi xoa phan tu " << target << ": "; for (int num : v) { std::cout << num << " "; } //Bài đăng tại freetuts.net std::cout << std::endl; return 0; }
Kết quả:
Ví dụ về tính tổng, min, max của một dãy số
#include <iostream> #include <vector> #include <algorithm> #include <numeric> int main() { std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6}; int sum = std::accumulate(v.begin(), v.end(), 0); auto min_it = std::min_element(v.begin(), v.end()); //Bài đăng tại freetuts.net auto max_it = std::max_element(v.begin(), v.end()); std::cout << "Tong cac phan tu: " << sum << std::endl; std::cout << "Gia tri nho nhat: " << *min_it << std::endl; std::cout << "Gia tri lon nhat: " << *max_it << std::endl; return 0; }
Kết quả:
Kết bài
Trong bài viết này, mình đã thảo luận về một số hàm Algorithm quan trọng trong STL của C++ và cung cấp các ví dụ minh họa chi tiết để giúp hiểu rõ cách sử dụng chúng. Việc hiểu và thành thạo trong việc sử dụng các hàm Algorithm này sẽ giúp bạn viết code hiệu quả hơn, dễ đọc hơn và giảm thiểu các lỗi trong quá trình phát triển phần mềm.
Nếu bạn muốn tăng thêm kiến thức và kỹ năng về STL và các hàm Algorithm, hãy tiếp tục thực hành và nghiên cứu các tài liệu và ví dụ khác từ nguồn tin cậy. Hy vọng bài viết này đã hữu ích và giúp bạn có cái nhìn tổng quan về cách sử dụng các hàm Algorithm trong STL của C++.