C++ 删除数组中的偶数并移动元素
我试着写一个代码,研究偶数,然后删除偶数,然后移动所有其他元素 i表示偏移量,是数组中元素的实际位置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;
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';
}