C++ 删除数组中的偶数并移动元素

C++ 删除数组中的偶数并移动元素,c++,arrays,shift,C++,Arrays,Shift,我试着写一个代码,研究偶数,然后删除偶数,然后移动所有其他元素 i表示偏移量,是数组中元素的实际位置 int k; for(i=0; i < N; i++) { if(Array[i] % 2 == 0) { for(k=i+1; k < N; k++) { Array[k-1] = Array[k]; } N--; } } k是偶数在数组中的位置 int k; for(i=0;

我试着写一个代码,研究偶数,然后删除偶数,然后移动所有其他元素

i表示偏移量,是数组中元素的实际位置

int k;
for(i=0; i < N; i++)
{
    if(Array[i] % 2 == 0)
    {
       for(k=i+1; k < N; k++)
       {
            Array[k-1] = Array[k];
       }
       N--;
    }
}
k是偶数在数组中的位置

int k;
for(i=0; i < N; i++)
{
    if(Array[i] % 2 == 0)
    {
       for(k=i+1; k < N; k++)
       {
            Array[k-1] = Array[k];
       }
       N--;
    }
}
Array=[2,10,3,5,8,7,3,3,7,10]应删除偶数,但10 停留在数组中=[10,3,5,7,3,3,7]

现在我已经花了3个多小时试图找出代码中的错误。

您可以使用std::vector和标准函数std::erase\u如果+vectors erase函数来执行此操作:

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

int main() {
    std::vector<int> Array = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};

    auto it = std::remove_if(
        Array.begin(),
        Array.end(),
        [](int x) { return (x & 1) == 0 && x != 10; }
    );

    Array.erase(it, Array.end());

    for(int x : Array) {
        std::cout << x << "\n";
    }
}
编辑:以艰难的方式完成:

#include <iostream>

int main() {
    int Array[] = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
    size_t N = sizeof(Array) / sizeof(int);

    for(size_t i = 0; i < N;) {
        if((Array[i] & 1) == 0 && Array[i] != 10) {
            for(size_t k = i + 1; k < N; ++k) {
                Array[k - 1] = Array[k];
            }
            --N;
        } else
            ++i; // only step i if you didn't shift the other values down
    }
    for(size_t i = 0; i < N; ++i) {
        std::cout << Array[i] << "\n";
    }
}
或更简单:

#include <iostream>

int main() {
    int Array[] = {2, 10, 3, 5, 8, 7, 3, 3, 7, 10};
    size_t N = sizeof(Array) / sizeof(int);
    size_t k = 0;

    for(size_t i = 0; i < N; ++i) {
        if((Array[i] & 1) || Array[i] == 10) {
            // step k after having saved this value 
            Array[k++] = Array[i];
        }
    }
    N = k;
    for(size_t i = 0; i < N; ++i) {
        std::cout << Array[i] << "\n";
    }
}

> C++中的惯用解决方案是使用STL算法。< /P> 此示例使用C样式的数组

int Array[100] = {2,10,3,5,8,7,3,3,7,10};
int N = 10;

// our remove_if predicate
auto removeEvenExceptFirst10 = [first10 = true](int const& num) mutable {
    if (num == 10 && first10) {
        first10 = false;
        return false;
    }

    return num % 2 == 0;
};

auto newN = std::remove_if(
    std::begin(Array), std::begin(Array) + N,
    removeEvenExceptFirst10
);

N = std::distance(std::begin(Array), newN);

这似乎是某种家庭作业或学校作业。那么,发布的代码的实际问题是什么

这就是当你移除索引i上的一个偶数时,你把索引i+1上的那个数放到索引i中。然后继续外循环迭代,它将检查索引i+1,它是数组中原始i+2位置的数字。因此,从数组[i+1]开始,现在在数组[i]中的数字永远不会被检查


解决这一问题的一个简单方法是在减少N时减少i。

虽然已经回答了,但我看不出人们为什么要通过双for循环来驱动i,每次减少都会重复地移动数据

我完全同意关于使用容器的所有建议。此外,算法解决方案不需要容器,您可以在本机阵列上使用它,但容器仍然使它更容易和更干净。也就是说

我在上面的一般评论中描述了这个算法。这不需要嵌套循环。您需要一个读指针和一个写指针。就这样

如果你认为这没有什么区别,我邀请你用一百万个随机整数填充一个数组,然后尝试两种解决方案,即嵌套for循环方法和上面看到的方法

在本机阵列上使用std::remove_if

仅为清楚起见,上面的代码基本上与标准算法std::remove_if的功能相同。我们所需要做的就是提供迭代器——数组偏移量和大小将很好地工作,并且知道如何解释结果

#include <iostream>
#include <algorithm>

int main()
{
    int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
    auto it = std::remove_if(std::begin(arr), std::end(arr),
                             [](int x){ return x%2 == 0; });

    for (size_t i=0; i<(it - arr); ++i)
        std::cout << arr[i] << ' ';
    std::cout << '\n';
}

相同的结果。

这是通过数组、单个读取指针、单个写入指针和单个for循环实现的。除此之外的任何事情都是不必要的。否则,您将不必要地一次又一次地复制相同的元素。仅供参考,您缩减的数组的最后一个长度是wptr-array,其中wptr是您一直在管理的写指针。std::transform可能会很方便地实现这一点。数组是如何定义的?如果不使用k变量,您似乎不会删除itSo中的任何元素?请再次阅读WhozCraig上面的注释。。。然后离开键盘,想想。。。只有一个用于循环。。。内部循环检查元素是否为偶数。。。如果偶数,则将您的AvailableInter更新为此偶数元素的索引。。。在好的非偶数上,将值移动到与可用间隔匹配的数组索引中。。。这就是你要做的。我应该只使用简单的代码,比如移动和移位。我也试着像这样使用这个代码,但我的老师拒绝了,并要求没有简单的代码;我明白了,因为这一点,我不得不接受它。增加了一个版本。OP说解决方案只能使用普通数组,不能使用现代数组techniques@ScottStensland好的,这使用了平面阵列
#include <iostream>
#include <algorithm>

int main()
{
    int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
    auto it = std::remove_if(std::begin(arr), std::end(arr),
                             [](int x){ return x%2 == 0; });

    for (size_t i=0; i<(it - arr); ++i)
        std::cout << arr[i] << ' ';
    std::cout << '\n';
}
#include <iostream>
#include <algorithm>

int main()
{
    int arr[] = { 2,10,3,5,8,7,3,3,7,10 };
    auto it = std::remove_if(std::begin(arr), std::end(arr),
                             [](int x){ return x%2 == 0; });

    for (size_t i=0; i<(it - arr); ++i)
        std::cout << arr[i] << ' ';
    std::cout << '\n';
}