【C++之泛型算法】014变序型算法

反转元素次序

reverse()

std::reverse 是 C++ 标准库中的一个泛型算法,用于反转给定范围内元素的顺序。这个算法定义在 头文件中。以下是 std::reverse 的声明:

template <class BidirectionalIterator>
void reverse(BidirectionalIterator first, BidirectionalIterator last);

std::reverse 接受两个双向迭代器 first 和 last,它们定义了要反转的元素范围。first 指向范围中的第一个元素,last 指向范围中的最后一个元素之后的位置。这个算法会原地(in-place)反转元素,不需要额外的存储空间。

下面是一些使用 std::reverse 的例子:
基本用法

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};

    // 反转 vector 中的元素
    std::reverse(v.begin(), v.end());

    // 输出反转后的 vector
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出将会是:

5 4 3 2 1

在数组上使用

#include <iostream>
#include <algorithm>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int size = sizeof(arr) / sizeof(arr[0]);

    // 反转数组中的元素
    std::reverse(arr, arr + size);

    // 输出反转后的数组
    for (int i = 0; i < size; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出同样会是:

5 4 3 2 1

反转字符串中的字符

#include <iostream>
#include <algorithm>
#include <string>

int main() {
    std::string s = "Hello, World!";

    // 反转字符串中的字符
    std::reverse(s.begin(), s.end());

    // 输出反转后的字符串
    std::cout << s << std::endl;

    return 0;
}

输出将会是:

!dlroW ,olleH

在使用 std::reverse 时,请注意它不会检查容器或数组是否为空,也不会检查 first 和 last 是否合法。因此,确保你传递给 std::reverse 的迭代器是有效的,并且 first 不晚于 last。此外,由于 std::reverse 是就地操作,因此它不会返回任何值(返回类型为 void)。

reverse_copy()

std::reverse_copy 是 C++ 标准库中的一个泛型算法,它用于将源序列中的元素反向复制到目标序列中。该算法不会改变源序列的原始顺序。以下是 std::reverse_copy 的声明:

template <class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator d_first);

这个算法接受三个参数:

  • first 和 last:这两个参数定义了源序列的范围,first 指向源序列的第一个元素,last 指向源序列的最后一个元素之后的位置。
  • d_first:这个参数指向目标序列的第一个元素,算法会将源序列中反向的元素复制到这个位置开始的目标序列中。

下面是一个 std::reverse_copy 的具体用法示例:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // 源序列
    std::vector<int> source = {1, 2, 3, 4, 5};

    // 目标序列,需要有足够的空间来存放源序列的元素
    std::vector<int> destination(source.size());

    // 使用 reverse_copy 将源序列反向复制到目标序列
    std::reverse_copy(source.begin(), source.end(), destination.begin());

    // 输出目标序列
    for (const auto& element : destination) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出将会是:

5 4 3 2 1

在这个例子中,std::reverse_copy 将 source 向量中的元素反向复制到 destination 向量中。因此,destination 向量现在包含了 source 向量元素的反向副本。

请注意,目标序列 destination 必须具有足够的空间来容纳源序列的所有元素。如果目标序列的大小不足以容纳所有元素,将会导致未定义行为。在这个例子中,我们通过为 destination 分配与 source 相同大小的空间来确保有足够的空间。

旋转元素

rotate()

std::rotate 是 C++ 标准库中的一个泛型算法,用于在给定范围内旋转元素。这个算法会将范围内的元素循环移动,使得一个指定的元素或一系列元素成为范围的开始。

std::rotate 的声明如下:

template <class ForwardIt>
void rotate(ForwardIt first, ForwardIt middle, ForwardIt last);

std::rotate 接受三个前向迭代器:first、middle 和 last。这些迭代器定义了要旋转的序列的范围,其中 first 指向序列的第一个元素,last 指向序列的最后一个元素之后的位置,而 middle 指向旋转后将成为序列第一个元素的位置。

以下是 std::rotate 的具体用法示例:
基本用法

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v = {0, 1, 2, 3, 4};

    // 将元素向右旋转两个位置
    std::rotate(v.begin(), v.begin() + 2, v.end());

    // 输出旋转后的 vector
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出将会是:

2 3 4 0 1

在这个例子中,std::rotate 将 v 向量中的元素向右旋转了两个位置。原来的前两个元素 0 和 1 移动到了序列的末尾。
使用 std::rotate_copy

如果你想要旋转元素但不改变原始序列,可以使用 std::rotate_copy 算法:

template <class InputIt, class OutputIt, class Size>
OutputIt rotate_copy(InputIt first, InputIt middle, InputIt last, OutputIt d_first, Size n);

std::rotate_copy 的用法类似于 std::rotate,但是它需要一个额外的输出迭代器 d_first,用于指定将旋转后的序列复制到哪个位置。此外,它还需要一个 Size 类型的参数 n,表示旋转的元素数量。
使用自定义比较

std::rotate 不支持自定义比较函数,因为它总是按照元素的顺序进行旋转。如果需要更复杂的重排逻辑,可能需要使用其他算法,如 std::partition 或 std::stable_partition。

请注意,std::rotate 可能会改变序列中元素的相对顺序,但它不会改变元素的绝对值。此外,由于旋转操作可能涉及移动元素,因此它对于大型容器或复杂类型的元素可能会相对较慢。

排列元素

next_permutation()

std::next_permutation 是 C++ 标准库 头文件中提供的一个泛型算法,用于对容器中的元素进行全排列。这个算法会按照字典序生成给定序列的下一个排列。如果当前排列已经是所有可能排列中的最后一个,则该函数会重新排列容器中的元素,使其变成最小的排列。

下面是 std::next_permutation 的所有声明和具体用法:
声明

template< class BidirectionalIterator >
bool next_permutation( BidirectionalIterator first, BidirectionalIterator last );

template< class BidirectionalIterator, class Compare >
bool next_permutation( BidirectionalIterator first, BidirectionalIterator last, Compare comp );

用法
基本用法

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3};

    // 打印所有可能的排列
    do {
        // 输出当前排列
        for (int num : vec) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    } while (std::next_permutation(vec.begin(), vec.end()));

    return 0;
}

带比较函数的用法

如果你想使用自定义的比较函数来替代默认的 < 操作符,你可以提供第三个参数:

#include <iostream>
#include <vector>
#include <algorithm>

// 自定义比较函数
bool myCompare(int a, int b) {
    return a < b; // 这里只是示范,实际上与默认的比较相同
}

int main() {
    std::vector<int> vec = {1, 2, 3};

    // 使用自定义比较函数打印所有可能的排列
    do {
        // 输出当前排列
        for (int num : vec) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    } while (std::next_permutation(vec.begin(), vec.end(), myCompare));

    return 0;
}

返回值

std::next_permutation 返回一个布尔值:
  • 如果成功生成了下一个排列,则返回 true。
  • 如果当前排列已经是最后一个排列,并且无法生成下一个排列,则返回 false。

注意事项

  • std::next_permutation 会修改传入的容器,以反映生成的下一个排列。
  • 容器中的元素必须是可以交换的,并且容器类型必须是双向迭代器支持的,例如 std::vector、std::list、std::deque 等。
  • 自定义比较函数应该满足严格弱序关系。

示例输出

对于 vec = {1, 2, 3},上述代码将输出:

1 2 3 
1 3 2 
2 1 3 
2 3 1 
3 2 1 
3 1 2

这显示了所有可能的排列。当 std::next_permutation 返回 false 时,vec 将包含其最小排列 {1, 2, 3}。

prev_permutation()

std::prev_permutation 是 C++ 标准库 头文件中提供的另一个泛型算法,与 std::next_permutation 相反,它用于生成给定序列的上一个排列。如果当前排列已经是所有可能排列中的第一个,即字典序最小的排列,该函数会重新排列容器中的元素,使其变成最大的排列。
声明

std::prev_permutation 的声明如下:

template< class BidirectionalIterator >
bool prev_permutation( BidirectionalIterator first, BidirectionalIterator last );

template< class BidirectionalIterator, class Compare >
bool prev_permutation( BidirectionalIterator first, BidirectionalIterator last, Compare comp );

用法
基本用法

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {3, 2, 1};

    // 打印所有可能的排列
    do {
        // 输出当前排列
        for (int num : vec) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    } while (std::prev_permutation(vec.begin(), vec.end()));

    return 0;
}

带比较函数的用法

你也可以提供一个自定义的比较函数作为第三个参数,以替代默认的 < 操作符:

#include <iostream>
#include <vector>
#include <algorithm>

// 自定义比较函数
bool myCompare(int a, int b) {
    return a < b; // 这里只是示范,实际上与默认的比较相同
}

int main() {
    std::vector<int> vec = {3, 2, 1};

    // 使用自定义比较函数打印所有可能的排列
    do {
        // 输出当前排列
        for (int num : vec) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    } while (std::prev_permutation(vec.begin(), vec.end(), myCompare));

    return 0;
}

返回值

std::prev_permutation 返回一个布尔值:

  • 如果成功生成了上一个排列,则返回 true。
  • 如果当前排列已经是第一个排列,并且无法生成上一个排列,则返回 false。

注意事项

  • std::prev_permutation 会修改传入的容器,以反映生成的上一个排列。
  • 容器中的元素必须是可以交换的,并且容器类型必须是双向迭代器支持的,例如 std::vector、std::list、std::deque 等。
  • 自定义比较函数应该满足严格弱序关系。

示例输出

对于 vec = {3, 2, 1},上述代码将输出:

3 2 1 
3 1 2 
2 3 1 
2 1 3 
1 3 2 
1 2 3

这显示了所有可能的排列。当 std::prev_permutation 返回 false 时,vec 将包含其最大排列 {3, 2, 1}

对元素重新洗牌

shuffle()

std::shuffle 是 C++ 标准库 头文件中提供的一个泛型算法,用于对容器中的元素进行随机重新排列,即洗牌。这个算法接受一个随机数生成器作为参数,以便产生随机数来决定元素的新位置。
声明

std::shuffle 的声明如下:

template< class RandomIt, class RandomNumberGenerator >
void shuffle( RandomIt first, RandomIt last, RandomNumberGenerator&& g );

template< class RandomIt, class RandomNumberGenerator, class UniformRandomBitGenerator >
void shuffle( RandomIt first, RandomIt last, RandomNumberGenerator g, UniformRandomBitGenerator&& gen );

用法
基本用法

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    // 使用默认随机引擎和均匀分布
    std::random_device rd;
    std::mt19937 g(rd());

    // 对 vec 进行随机洗牌
    std::shuffle(vec.begin(), vec.end(), g);

    // 输出洗牌后的结果
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

使用自定义的随机数生成器

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 自定义随机数生成器
    std::random_device rd;
    std::uniform_int_distribution<> dis(0, vec.size() - 1);
    std::function<int()> gen(std::bind(dis, rd));

    // 对 vec 进行随机洗牌
    std::shuffle(vec.begin(), vec.end(), gen);

    // 输出洗牌后的结果
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

参数

  • first 和 last:定义要洗牌的序列范围的迭代器。
  • g:随机数生成器,可以是任何满足 UniformRandomBitGenerator 要求的类型,或者任何可以调用以生成随机数的函数对象。
  • gen(第二个声明中的):一个满足 UniformRandomBitGenerator 要求的随机数生成器。

返回值

std::shuffle 没有返回值,它直接修改传入的容器。
注意事项

  • 容器中的元素类型必须支持赋值操作。
  • 随机数生成器必须是有效的,并且能够产生足够多的随机数来覆盖所有可能的排列。
  • std::shuffle 是就地算法,即它直接在输入序列上操作,不需要额外的存储空间。

示例输出

每次运行程序,std::shuffle 都会产生不同的随机排列。因此,输出将会是不同的随机整数序列。

random_shuffle()

在 C++ 标准库中,std::random_shuffle 是一个泛型算法,用于对序列中的元素进行随机重排。该算法在 C++14 中仍然存在,但在 C++17 中被 std::shuffle 的新重载所取代。std::random_shuffle 的声明如下:

template< class RandomIt >
void random_shuffle( RandomIt first, RandomIt last );

template< class RandomIt, class RandomNumberGenerator >
void random_shuffle( RandomIt first, RandomIt last, RandomNumberGenerator&& g );

第一个声明不接受任何随机数生成器,而是使用默认的全局随机数生成器 std::random_device 和默认的均匀分布 std::uniform_int_distribution。这种用法在现代 C++ 中已经不推荐,因为它缺乏灵活性和可预测性。

第二个声明接受一个随机数生成器 g,该生成器必须满足 UniformRandomBitGenerator 的要求,或者是一个可以调用以生成随机数的函数对象。
具体用法

以下是 std::random_shuffle 的一个示例用法,其中使用了一个自定义的随机数生成器:

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 使用默认的全局随机数生成器
    std::random_shuffle(v.begin(), v.end());

    // 或者使用自定义的随机数生成器
    std::random_device rd;  // 用于获得随机数种子
    std::mt19937 g(rd());   // Mersenne Twister 随机数生成器
    std::shuffle(v.begin(), v.end(), g);  // 注意:这里使用 C++17 的 std::shuffle

    // 输出随机重排后的向量
    for (int i : v) {
        std::cout << i << ' ';
    }
    std::cout << std::endl;

    return 0;
}

请注意,在上面的示例中,我使用了 std::shuffle 而不是 std::random_shuffle,因为 std::shuffle 是 C++17 中推荐使用的函数,并且它提供了更多的灵活性。如果你正在使用 C++17 或更高版本,建议使用 std::shuffle。
注意事项

  • std::random_shuffle 在 C++17 中已被弃用,并在 C++20 中被移除。因此,建议使用 std::shuffle。
  • 传递给 std::random_shuffle 或 std::shuffle 的随机数生成器必须是有效的,并且必须能够产生足够多的随机数来覆盖所有可能的排列。
  • 容器中的元素类型必须支持赋值操作。
  • 随机数生成器的种子(seed)应该被设置为一个不可预测的值,以确保每次程序运行时都能得到不同的随机序列。

C++17 中的 std::shuffle

在 C++17 中,std::shuffle 得到了扩展,可以接受两个随机数生成器,一个用于生成随机数,另一个用于转换这些随机数。然而,std::random_shuffle 没有得到这样的扩展,并且在 C++20 中被完全移除。因此,对于 C++17 及更高版本,应始终使用 std::shuffle。

元素向前搬

partition()

在 C++ 标准库中,std::partition 是一个泛型算法,用于对序列中的元素进行重新排列,使得满足某个谓词的元素都出现在不满足该谓词的元素之前。它不接受一个严格意义上的"partition key",而是使用一个谓词(即返回布尔值的函数或函数对象)来决定哪些元素应该出现在分区的哪一部分。

std::partition 的声明如下:

template< class ForwardIt, class UnaryPredicate >
ForwardIt partition( ForwardIt first, ForwardIt last, UnaryPredicate p );

template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >
ForwardIt partition( ExecutionPolicy&& exec, ForwardIt first, ForwardIt last, UnaryPredicate p );

第一个声明是一个非并行版本,它接受一对前向迭代器(first 和 last),表示要操作的序列范围,以及一个一元谓词 p,该谓词接受一个元素作为参数并返回一个布尔值。

第二个声明是一个并行版本,它接受一个执行策略 exec,用于指定算法的执行方式(例如,并行执行),以及和第一个声明相同的迭代器范围和谓词。
具体用法

下面是一个 std::partition 的示例用法:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // 使用 lambda 表达式作为谓词,将偶数放在前面,奇数放在后面
    auto partition_point = std::partition(v.begin(), v.end(), [](int n) {
        return n % 2 == 0;
    });

    // 输出分区后的结果
    for (const auto& num : v) {
        std::cout << num << ' ';
    }
    std::cout << std::endl;

    // 输出分区点,即第一个不满足谓词的元素的位置
    std::cout << "Partition point: " << std::distance(v.begin(), partition_point) << std::endl;

    return 0;
}

在上面的例子中,std::partition 将所有偶数放在了向量的前面,所有奇数放在了后面。std::partition 返回的是一个迭代器,它指向第一个不满足谓词的元素。在输出中,你会看到所有的偶数都在这个迭代器之前,而所有的奇数都在这个迭代器之后。
注意事项

  • std::partition 不保证保持等价元素的相对顺序。也就是说,对于满足谓词的元素之间,以及不满足谓词的元素之间,它们的相对顺序可能会发生变化。
  • 谓词函数应该是一个返回布尔值的函数或函数对象,它接受一个序列中的元素作为参数。
  • std::partition 是一个稳定算法,即等价元素的相对顺序不会改变。
  • 并行版本的 std::partition(第二个声明)在 C++17 中引入,它允许算法在支持并行执行的环境中并行运行,以提高性能。然而,请注意,并行算法的正确使用需要理解其执行策略和可能的线程安全问题。

在使用 std::partition 时,请确保你的谓词函数是正确且高效的,因为它将直接影响算法的性能和正确性。

stable_partition()

std::stable_partition 是 C++ 标准库中的一个泛型算法,它对序列中的元素进行重新排列,使得满足特定谓词的元素出现在不满足该谓词的元素之前,同时保持等价元素之间的相对顺序不变。这个算法是稳定的,意味着等价元素的相对顺序在分区操作前后保持不变。

std::stable_partition 的声明如下:

cpp
template< class ForwardIt, class UnaryPredicate >
ForwardIt stable_partition( ForwardIt first, ForwardIt last, UnaryPredicate p );

template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >
ForwardIt stable_partition( ExecutionPolicy&& exec, ForwardIt first, ForwardIt last, UnaryPredicate p );

第一个声明是一个非并行版本,它接受一对前向迭代器(first 和 last),表示要操作的序列范围,以及一个一元谓词 p,该谓词接受一个元素作为参数并返回一个布尔值。

第二个声明是一个并行版本,它接受一个执行策略 exec,用于指定算法的执行方式(例如,并行执行),以及和第一个声明相同的迭代器范围和谓词。
具体用法

下面是一个 std::stable_partition 的示例用法:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // 使用 lambda 表达式作为谓词,将偶数放在前面,奇数放在后面,保持相对顺序不变
    auto partition_point = std::stable_partition(v.begin(), v.end(), [](int n) {
        return n % 2 == 0;
    });

    // 输出分区后的结果
    for (const auto& num : v) {
        std::cout << num << ' ';
    }
    std::cout << std::endl;

    // 输出分区点,即第一个不满足谓词的元素的位置
    std::cout << "Stable partition point: " << std::distance(v.begin(), partition_point) << std::endl;

    return 0;
}

在上面的例子中,std::stable_partition 将所有偶数放在了向量的前面,所有奇数放在了后面。与 std::partition 不同,std::stable_partition 保证了相同类型的元素(在这里是偶数和奇数)之间的相对顺序不会改变。这意味着,例如,如果原始序列中有两个连续的偶数,那么分区后这两个偶数仍然会相邻。
注意事项

  • std::stable_partition 是一个稳定算法,即等价元素的相对顺序不会改变。
  • 谓词函数应该是一个返回布尔值的函数或函数对象,它接受一个序列中的元素作为参数。
  • 算法返回的是一个迭代器,指向第一个不满足谓词的元素。
  • 并行版本的 std::stable_partition(第二个声明)在 C++17 中引入,它允许算法在支持并行执行的环境中并行运行,以提高性能。然而,请注意,并行算法的正确使用需要理解其执行策略和可能的线程安全问题。

在使用 std::stable_partition 时,请确保你的谓词函数是正确且高效的,因为它将直接影响算法的性能和正确性。

划分为两个子区间

partition_copy()

std::partition_copy 是 C++ 标准库中的一个泛型算法,它用于将输入范围内的元素根据指定的谓词复制到两个输出范围中。满足谓词的元素被复制到第一个输出范围,不满足谓词的元素被复制到第二个输出范围。这个算法通常用于将元素分成两类。

std::partition_copy 的声明如下:

template< class InputIt, class OutputIt1, class OutputIt2, class UnaryPredicate >
std::tuple<OutputIt1, OutputIt2>
partition_copy( InputIt first, InputIt last, OutputIt1 out_true, OutputIt2 out_false, UnaryPredicate p );

template< class ExecutionPolicy, class ForwardIt, class OutputIt1, class OutputIt2, class UnaryPredicate >
std::tuple<OutputIt1, OutputIt2>
partition_copy( ExecutionPolicy&& exec, ForwardIt first, ForwardIt last, OutputIt1 out_true, OutputIt2 out_false, UnaryPredicate p );

第一个声明是一个非并行版本,它接受以下参数:

  • first 和 last:定义输入范围的迭代器。
  • out_true:指向第一个输出范围的迭代器,用于存放满足谓词的元素。
  • out_false:指向第二个输出范围的迭代器,用于存放不满足谓词的元素。
  • p:一元谓词,它接受一个元素并返回一个布尔值。

第二个声明是一个并行版本,它接受一个执行策略 exec,用于指定算法的执行方式(例如,并行执行),以及和第一个声明相同的输入、输出范围和谓词。
具体用法

下面是一个 std::partition_copy 的示例用法:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main() {
    std::vector<int> input = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    std::vector<int> even, odd;

    // 使用 lambda 表达式作为谓词,将偶数复制到 even,奇数复制到 odd
    auto [even_end, odd_end] = std::partition_copy(
        input.begin(), input.end(),
        std::back_inserter(even), std::back_inserter(odd),
        [](int n) { return n % 2 == 0; }
    );

    // 输出偶数向量
    std::cout << "Even numbers: ";
    for (const auto& num : even) {
        std::cout << num << ' ';
    }
    std::cout << std::endl;

    // 输出奇数向量
    std::cout << "Odd numbers: ";
    for (const auto& num : odd) {
        std::cout << num << ' ';
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,std::partition_copy 使用一个 lambda 表达式来判断每个元素是否为偶数。所有偶数都被添加到 even 向量中,所有奇数都被添加到 odd 向量中。std::back_inserter 是一个迭代器适配器,它生成一个可以将元素追加到容器末尾的迭代器。

std::partition_copy 返回一个 std::tuple,其中包含两个迭代器:even_end 指向 even 向量中最后一个被复制的元素之后的位置,odd_end 指向 odd 向量中最后一个被复制的元素之后的位置。
注意事项

  • std::partition_copy 保证所有满足谓词的元素都会出现在第一个输出范围中,不满足谓词的元素会出现在第二个输出范围中。
  • 输出范围必须足够大,以容纳所有可能的元素。否则,可能会导致迭代器失效或未定义行为。
  • 并行版本的 std::partition_copy(第二个声明)在 C++17 中引入,允许算法在支持并行执行的环境中并行运行。使用执行策略时,请确保理解其语义和可能的线程安全问题。
  • std::partition_copy 不保证保持等价元素的相对顺序。也就是说,在输出范围内,满足谓词或不满足谓词的元素之间的相对顺序可能会发生变化。
  • 23
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊猫Devin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值