21- C++ STL 알고리즘-9(C++)

10.3 알고리즘

10.3.1 정렬 알고리즘

10.3.1.1 sort() 정렬 함수

  • sort() 함수는 퀵 정렬을 기반으로 구현됩니다.

  • sort() 함수는 기본 구현에 의해 제한되며 일반 배열 및 일부 유형의 컨테이너에서만 작동합니다. 즉, sort() 함수는 다음 조건이 있는 일반 배열 및 컨테이너에만 사용할 수 있습니다.

    • 컨테이너에서 지원하는 반복기 유형은 임의 액세스 반복기여야 합니다. 즉, sort()는 vector와 deque라는 두 개의 컨테이너만 지원합니다.

    • 컨테이너의 지정된 영역에 있는 요소가 기본적으로 오름차순으로 정렬되는 경우 요소 유형은 <보다 작음 연산자를 지원해야 합니다. 규칙의 기본 구현에서 사용하는 비교 연산자

    • sort() 함수가 정렬을 구현할 때 컨테이너에 있는 요소의 저장 위치를 ​​교환해야 합니다. 이 경우 사용자 지정 클래스 개체가 컨테이너에 저장되어 있으면 생성자 및 대입 연산자의 오버로드를 클래스 내부에 복사해야 합니다.

    • sort() 정렬이 불안정합니다.

#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector
using namespace std;
//以普通函数的方式实现自定义排序规则
bool mycomp(int i, int j) {
    return (i < j);
}
//以函数对象的方式实现自定义排序规则
class mycomp2 {
public:
    bool operator() (int i, int j) {
        return (i < j);
    }
};
int main() {
	int a[] = { 32, 71, 12, 45, 26, 80, 53, 33 };
    vector<int> myvector(a, a+8);
    //调用第一种语法格式,对 32、71、12、45 进行排序
    sort(myvector.begin(), myvector.begin() + 4); //(12 32 45 71) 26 80 53 33
    //调用第二种语法格式,利用STL标准库提供的其它比较规则(比如 greater<T>)进行排序
    sort(myvector.begin(), myvector.begin() + 4, greater<int>()); //(71 45 32 12) 26 80 53 33
   
    //调用第二种语法格式,通过自定义比较规则进行排序
    sort(myvector.begin(), myvector.end(), mycomp2());//12 26 32 33 45 53 71 80
    //输出 myvector 容器中的元素
    for (vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
        cout << *it << ' ';
    }
    return 0;
}

10.3.1.2 stable_sort() 정렬 알고리즘

  • stable_sort() 함수는 병합 정렬을 기반으로 구현됩니다.

  • stable_sort()는 안정적인 정렬 알고리즘입니다.

  • stable_sort() 함수는 sort() 함수와 같은 방식으로 사용됩니다.

10.3.1.3 partial_sort() 정렬 함수

1. 소개

  • 이런 상황을 가정하면 100만 개의 요소가 있는 컨테이너가 있는데 가장 작은 값을 가진 10개의 요소만 추출하고 싶은데 어떻게 하면 될까요?

    • 이전 학습을 통해 sort() 또는 stable_sort() 정렬 함수, 즉 컨테이너에 저장된 100만 개의 요소를 정렬하여 가장 작은 10개의 요소를 성공적으로 필터링할 수 있다고 생각할 수 있습니다. 그러나 단지 10개의 요소를 추출하기 위해서는 먼저 100만 개의 요소를 정렬해야 하는데, 이 구현의 효율성이 매우 낮다고 생각할 수 있습니다.

    • 유사한 문제를 해결하기 위해 C++ STL 표준 라이브러리는 partial_sort()를 사용하여 보다 효율적인 솔루션을 제공합니다.

  • 부분 정렬은 문자 그대로 "부분 정렬"로 번역될 수 있으며, 이 기능은 지정된 영역에서 데이터의 일부를 추출하여 정렬할 수 있습니다.

2. 문법적 형식

//按照默认的升序排序规则,对 [first, last) 范围的数据进行筛选并排序
void partial_sort (RandomAccessIterator first,
                   RandomAccessIterator middle,
                   RandomAccessIterator last);
//按照 comp 排序规则,对 [first, last) 范围的数据进行筛选并排序
void partial_sort (RandomAccessIterator first,
                   RandomAccessIterator middle,
                   RandomAccessIterator last,
                   Compare comp);
/*
其中,first、middle 和 last 都是随机访问迭代器,comp 参数用于自定义排序规则。
partial_sort() 函数会以交换元素存储位置的方式实现部分排序的。
具体来说,partial_sort() 会将 [first, last) 范围内最小(或最大)的 middle-first 个元素移动到 
[first, middle) 区域中,并对这部分元素做升序(或降序)排序。
*/

partial_sort() 함수는 기본 구현에 의해 제한되며 일반 배열 및 부분 유형 컨테이너에만 적용할 수 있습니다 . 즉, 다음 조건을 가진 일반 배열 및 컨테이너만 partial_sort() 함수를 사용할 수 있습니다.

  • partial_sort() 함수는 array, vector 및 deque 의 세 가지 컨테이너 에만 적용할 수 있습니다.

  • 기본 오름차순 정렬 규칙을 선택한 경우 컨테이너에 저장된 요소 유형은 <보다 작음 연산자를 지원해야 하며, 유사하게 표준 라이브러리에서 제공하는 다른 정렬 규칙을 선택한 경우 요소 유형도 컨테이너에서 사용하는 비교 연산자를 지원해야 합니다. 규칙의 기본 구현

  • partial_sort() 함수를 구현하는 동안 특정 요소의 저장 위치를 ​​교환해야 합니다. 따라서 사용자 지정 클래스 개체가 컨테이너에 저장되어 있는 경우 클래스는 이동 생성자와 이동 할당 연산자를 제공해야 합니다.

#include <iostream>     // std::cout
#include <algorithm>    // std::partial_sort
#include <vector>       // std::vector
using namespace std;
//以普通函数的方式自定义排序规则
bool mycomp1(int i, int j) {
    return (i > j);
}
//以函数对象的方式自定义排序规则
class mycomp2 {
public:
    bool operator() (int i, int j) {
        return (i > j);
    }
};
int main() {
    vector<int> myvector{ 3,2,5,4,1,6,9,7};
    //以默认的升序排序作为排序规则,将 myvector 中最小的 4 个元素移动到开头位置并排好序
    partial_sort(myvector.begin(), myvector.begin() + 4, myvector.end());
    cout << "第一次排序:\n";
    for (vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
        cout << *it << ' ';
    cout << "\n第二次排序:\n";
    // 以指定的 mycomp2 作为排序规则,将 myvector 中最大的 4 个元素移动到开头位置并排好序
    partial_sort(myvector.begin(), myvector.begin() + 4, myvector.end(), mycomp2());
    for (vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
        cout << *it << ' ';
    return 0;
}

10.3.1.4 merge() 함수

기능: 두 개의 정렬된 시퀀스를 하나의 정렬된 시퀀스로 병합

기본 데이터 정렬:

//以默认的升序排序作为排序规则
OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
                      InputIterator2 first2, InputIterator2 last2,
                      OutputIterator result);
//以自定义的 comp 规则作为排序规则
OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
                      InputIterator2 first2, InputIterator2 last2,
                      OutputIterator result, Compare comp);
/*
* firs1t为第一个容器的首迭代器,last1为第一个容器的末迭代器;
* first2为第二个容器的首迭代器,last2为容器的末迭代器;
* result为存放结果的容器,comapre为比较函数(可略写,默认为合并为一个升序序列)。
*/

참고: 결과를 사용할 때 벡터를 사용하는 경우 먼저 크기 조정을 사용하여 용량을 확장해야 합니다.

10.3.1.5 revrese() 함수

함수 매개변수: reverse(첫 번째, 마지막)

기능: 리버스 컨테이너

알아채다:

  • 문자열, 벡터 및 deque는 템플릿 라이브러리 알고리즘의 반전 기능만 사용할 수 있습니다.

  • 목록은 알고리즘과 목록 클래스에서 역순으로 사용할 수 있습니다.

  • 스택과 큐에는 반복자가 없으므로 당연히 알고리즘에서 역방향을 사용할 수 없으며 해당 클래스는 역방향 멤버 함수를 제공하지 않습니다.

  • set 및 map의 요소는 키 값에 따라 정렬되며 키 값은 수정 및 되돌릴 수 없습니다.

10.3.2 검색 알고리즘

10.3.2.1 인접_찾기()

기능: 반복자 쌍의 식별된 요소 범위 내에서 인접한 반복 요소 쌍을 찾고 발견된 경우 요소 쌍의 첫 번째 요소를 가리키는 반복자를 반환합니다.

vector<int> vecInt;
vecInt.push_back(1);
vecInt.push_back(2);
vecInt.push_back(2);
vecInt.push_back(4);
vecInt.push_back(5);
vecInt.push_back(5);
 
vector<int>::iterator it = adjacent_find(vecInt.begin(), vecInt.end()); //*it == 2

10.3.2.2 binary_search()

기능: 이진 검색 방법, 순서대로 값을 찾고, 찾으면 참을 반환합니다.

set<int> setInt;
setInt.insert(3);
setInt.insert(1);
setInt.insert(7);
setInt.insert(5);
setInt.insert(9);
 
bool bFind = binary_search(setInt.begin(),setInt.end(),5);

10.3.2.3 카운트()

기능: 등호 연산자를 사용하여 플래그 범위 내의 요소를 입력 값과 비교하고 같은 수를 반환합니다.

vector<int> vecInt;
vecInt.push_back(1);
vecInt.push_back(2);
vecInt.push_back(2);
vecInt.push_back(4);
vecInt.push_back(2);
vecInt.push_back(5);
int iCount = count(vecInt.begin(),vecInt.end(),2); //iCount==3

10.3.2.4 찾기()

기능: find() 함수는 지정된 범위 내에서 대상 요소와 값이 동일한 첫 번째 요소를 찾는 데 사용됩니다.

함수 구문은 다음과 같습니다.

InputIterator find (InputIterator first, InputIterator last, const T& val);

그 중 first와 last는 입력 반복자이고, [first, last)는 함수의 검색 범위를 지정하는 데 사용되며, val은 검색할 대상 요소입니다 .

first와 last는 입력 반복기이므로 이 함수는 모든 순차 컨테이너에서 작동합니다.

이 함수는 입력 반복자를 반환합니다. find() 함수가 검색에 성공하면 [first, last) 영역에서 찾은 첫 번째 대상 요소를 가리키고, 검색에 실패하면 반복자가 가리키고 last는 동일합니다.

find() 함수의 기본 구현은 실제로 연산자를 사용하여 val 및 [first, last) 영역의 요소를 하나씩 비교하는 것입니다. 이것은 또한 [first, last) 범위의 요소가 연산자를 지원해야 함을 의미합니다.

#include <iostream>     // std::cout
#include <algorithm>    // std::find
#include <vector>       // std::vector
using namespace std;
int main() {
    //find() 函数作用于普通数组
    char stl[] ="http://c.biancheng.net/stl/";
    //调用 find() 查找第一个字符 'c'
    char * p = find(stl, stl + strlen(stl), 'c');
    //判断是否查找成功
    if (p != stl + strlen(stl)) {
        cout << p << endl;
    }
    //find() 函数作用于容器
    vector<int> myvector{ 10,20,30,40,50 };
    vector<int>::iterator it;
    it = find(myvector.begin(), myvector.end(), 30);
    if (it != myvector.end())
        cout << "查找成功:" << *it;
    else
        cout << "查找失败";
    return 0;
}

10.3.2.5 find_if()

기능: find() 함수와 동일하며 find_if() 함수도 지정된 영역에서 검색 작업을 수행하는 데 사용됩니다. 차이점은 전자는 찾을 요소의 값을 명시적으로 지정해야 하는 반면 후자는 사용자 지정 검색 규칙을 허용한다는 것입니다.

#include <iostream>     // std::cout
#include <algorithm>    // std::find_if
#include <vector>       // std::vector
using namespace std;

//以函数对象的形式定义一个 find_if() 函数的查找规则
class mycomp2 {
public:
    bool operator()(const int& i) {
        return ((i % 2) == 1);
    }
};
int main() {
    vector<int> myvector{ 4,2,3,1,5 };
    //调用 find_if() 函数
    vector<int>::iterator it = find_if(myvector.begin(), myvector.end(), mycomp2());
    cout << "*it = " << *it;
    return 0;
}

10.3.2.5 검색()

기능: search() 함수는 시퀀스 A에서 시퀀스 B의 첫 번째 항목을 찾는 데 사용됩니다.

예를 들어 다음 두 시퀀스를 고려하십시오.

시퀀스 B는 시퀀스 A에서 두 번 나타나는 것을 볼 수 있습니다. search() 함수의 도움으로 시퀀스 A에서 첫 번째 {1,2,3}을 찾을 수 있습니다.

search() 함수는 다음 두 가지 구문 형식을 제공합니다.

//查找 [first1, last1) 范围内第一个 [first2, last2) 子序列
ForwardIterator search (ForwardIterator first1, ForwardIterator last1,
                        ForwardIterator first2, ForwardIterator last2);
//查找 [first1, last1) 范围内,和 [first2, last2) 序列满足 pred 规则的第一个子序列
ForwardIterator search (ForwardIterator first1, ForwardIterator last1,
                        ForwardIterator first2, ForwardIterator last2,
                        BinaryPredicate pred);

그중 각 매개변수의 의미는 다음과 같습니다.

  • first1, last1: 둘 다 순방향 반복자 이며 [first1, last1) 조합을 사용하여 검색 범위(즉, 위의 예에서 시퀀스 A)를 지정합니다.

  • first2, last2: 둘 다 순방향 반복자 이며 [first2, last2) 조합은 검색할 시퀀스(즉, 위의 예에서 시퀀스 B)를 지정하는 데 사용됩니다.

  • pred: 조회 규칙을 사용자 지정하는 데 사용됩니다 . 규칙은 실제로 2개의 매개변수와 반환 유형이 bool인 함수입니다(첫 번째 매개변수는 [first1, last1) 범위의 요소를 받고 두 번째 매개변수는 [first2, last2) 범위의 요소를 받습니다). 함수 정의의 형식은 일반 함수 또는 함수 개체일 수 있습니다.

search() 함수는 순방향 반복자를 반환합니다 . 함수 검색이 성공하면 반복자는 찾은 하위 시퀀스의 첫 번째 요소를 가리키고 그렇지 않으면 검색이 실패하면 반복자는 마지막 반복자를 가리킵니다.

#include <iostream>     // std::cout
#include <algorithm>    // std::search
#include <vector>       // std::vector
using namespace std;
//以普通函数的形式定义一个匹配规则
bool mycomp1(int i, int j) {
    return (i%j == 0);
}
//以函数对象的形式定义一个匹配规则
class mycomp2 {
public:
    bool operator()(const int& i, const int& j) {
        return (i%j == 0);
    }
};
int main() {
    vector<int> myvector{ 1,2,3,4,8,12,18,1,2,3 };
    int myarr[] = { 1,2,3 };
    //调用第一种语法格式
    vector<int>::iterator it = search(myvector.begin(), myvector.end(), 
    myarr, myarr + 3);
    if (it != myvector.end()) {
        cout << "第一个{1,2,3}的起始位置为:" << it - myvector.begin() << ",*it = " << *it << endl;
    }
    int myarr2[] = { 2,4,6 };
    //调用第二种语法格式
    it = search(myvector.begin(), myvector.end(), 
    myarr2, myarr2 + 3, mycomp2());
    if (it != myvector.end()) {
        cout << "第一个{2,3,4}的起始位置为:" << it - myvector.begin() << ",*it = " << *it;
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/March_A/article/details/132053290
Recomendado
Clasificación