我做了以下一些代码来将零移动到数组的前面(顺便说一句,是否有更优雅高效的程序?)。出于某种原因,当我测试函数时,它不会修改数组,就像它应该做的那样。我无法弄清楚出了什么问题。
void zeros_to_front(int* arr, int sz) {
std::vector<int> nonzeroesVec;
for (int k = 0; k < sz; ++k) {
if (arr[k] != 0)
nonzeroesVec.push_back(arr[k]);
}
int numzeroes = sz - nonzeroesVec.size();
int j(0), k(0);
while (j < numzeroes)
arr[j++] = 0;
while (j < sz)
arr[j++] = nonzeroesVec[k++];
}
答案 0 :(得分:2)
如果您以后不关心非零元素的顺序,可以使用:
void swap(int& x, int& y)
{
x ^= y;
y ^= x;
x ^= y;
}
void zerosToFront(int arr[], int size)
{
if(size < 1)
{
return;
}
int front = 0;
for(int i = 0; i < size; i++)
{
if(arr[i] == 0)
{
swap(arr[i], arr[front++]);
}
}
}
它在数组中迭代一次,每当它找到零时,它就会将零交换到数组的前面。它是O(n)
,效率最高。
但是,如果您 关心订单,可以使用:
void zerosToFront(int arr[], int size)
{
if(size < 1)
{
return;
}
for(int i = 0; i < size; i++)
{
if(arr[i] == 0)
{
for(int j = 0; j < i; j++)
{
swap(arr[i - j], arr[i - j- 1]);
}
}
}
}
这会遍历数组一次,每当它找到零时,内部for循环基本上会将我们找到的零之前的所有内容移到右边,以便为列表开头的零腾出空间。但是,由于内部for循环,这是O(n^2)
,因此效率较低。但是对于相对较小的阵列,您不会注意到性能差异。
修改: 实际上,我刚刚意识到一些有趣的事情。如果向后遍历数组,则可以将零推到前面并在O(n)时间内保留非零元素的排序。
void ztf(int arr[], int size)
{
if(size < 1)
{
return;
}
int back = size - 1;
for(int i = size - 1; i >= 0; i--)
{
if(arr[i] != 0)
{
arr[back--] = arr[i];
}
}
while(back >= 0)
{
arr[back--] = 0;
}
}
只是觉得那太漂亮了。
答案 1 :(得分:1)
无论症状如何,我似乎无法重现它:
#include <stdio.h>
#include <vector>
void zeros_to_front(int* arr, int sz) {
std::vector<int> nonzeroesVec;
for (int k = 0; k < sz; ++k) {
if (arr[k] != 0)
nonzeroesVec.push_back(arr[k]);
}
int numzeroes = sz - nonzeroesVec.size();
int j(0), k(0);
while (j < numzeroes)
arr[j++] = 0;
while (j < sz)
arr[j++] = nonzeroesVec[k++];
}
int main(int argc,char *argv[])
{
int ptr[5] = {0};
ptr[0] = 1;
zeros_to_front(ptr,5);
for (int i = 0;i < 5;++i){
printf("%d",ptr[i]);
}
return 0;
}
按预期工作并打印出“00001”。
答案 2 :(得分:0)
我建议这样的事情:
#include <vector>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <iterator>
void
shake(int * arr, std::size_t N)
{
bool changed;
do
{
changed = false;
for (std::size_t i = 0; i != N - 1; ++i)
{
if (arr[i + 1] == 0 && arr[i] != 0)
{
std::swap(arr[i], arr[i + 1]);
changed = true;
}
}
}
while (changed);
}
int
main ()
{
std::vector<int> vec { 1, 0, 2, 0, 3, 0, 0, 4, 5, 0 };
shake(&vec[0], vec.size());
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(std::cout, ", "));
}