将矢量的元素向左推

Pushing elements of the vector to the left

本文关键字:元素      更新时间:2023-10-16

31 04 00 08

假设这是输入向量文件:

我该如何生成?

31 48 00 00

我想将所有非零数字从"04"推到左边。请帮忙!!

您可以使用以下内容在通过向量进行单次传递中执行此操作:

vector<int> v = {3, 1, 0, 4, 0, 0, 0, 8};
auto zero_iter = find(v.begin(), v.end(), 0);
for (auto curr_iter = zero_iter; curr_iter != v.end(); curr_iter++) {
    if (*curr_iter != 0) {
        swap(*curr_iter, *zero_iter);
        zero_iter++;
    }
}

这使用<algorithm>中的std::findstd::swap


这里的想法是跟踪第一个可用的零位置的位置,并在此之后找到非零位置。每次找到非零数时,您都会将其交换到第一个可用的零位置,并递增零位置以指向下一个位置。

至少在我看来

,到目前为止给出的解决方案有些不理想。

标准库提供了专门为手头的任务设计的算法。您正在尝试将输入划分为非零数字,后跟零。为此,std::stable_partition将正常工作:

std::string input = "31040008";
std::stable_partition(input.begin(), input.end(),
    [](auto c) { return c != '0'; });

结果:

31480000

如果您不关心非零数的顺序(只是它们都在零之前(,那么使用std::partition可能会获得一点速度。

您可以使用

std::remove删除所有 0。事实上,它只会将所有不为零的元素向左推,并返回要擦除的部分的开头。但是,您可以用 0 填充它,而不是擦除它:

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

int main()
{
    std::vector<int> v = { 3, 1, 0, 4, 0, 0, 0, 8 };
    std::fill(std::remove(v.begin(), v.end(), 0), v.end(), 0);

    //test
    for (auto d : v)
        std::cout << d << " ";
    std::cout << std::endl;
    return 0;
}

指纹:

3 1 4 8 0 0 0 0