【问题标题】:Removing zeros from an array and resizing the array to the new amount of elements?从数组中删除零并将数组大小调整为新的元素数量?
【发布时间】:2012-07-20 15:03:48
【问题描述】:

我在处理 C++ 数组中的数据时遇到了另一个问题。我现在想通过删除数组中的所有零来抽取数组。

例如说之前我有array[4] = {1,2,0,0,4} 它会变成array[3] = {1,2,4}

我知道我将需要使用 for 循环来遍历存储主要数据的数组,并且我很可能需要初始化一个新数组来存储抽取的数据,但我不太确定该怎么做它。

【问题讨论】:

  • 数组的大小是其类型的一部分,不能修改对象的类型。因此数组永远无法调整大小。您可以创建一个不同大小的新数组并复制元素。

标签: c++ arrays for-loop


【解决方案1】:

您无法调整普通数组的大小,因为它是静态分配的。因此,最好使用标准库 (STL) 中的vector。以这种方式,您不需要创建新数组。实际上,除非有充分的理由,否则使用 std::vectorstd::array(在 C++11 中)通常比使用普通的类 C 数组更好。

通过使用vector,您可以执行以下操作:

std::vector<int> v{1,2,0,0,4};
v.erase(
    std::remove(v.begin(), v.end(), 0),
    v.end());

删除零元素后,向量的容量仍然为 5(当然v.size() 将返回 3,正如预期的那样)。如果你可以使用 C++11,那么你可以走得更远一点:

v.shrink_to_fit();

shrink_to_fit 的调用会降低向量的容量,使其适应其中的实际元素数量(示例中为3)。这可能会节省内存(尤其是当向量中有很多元素时)。

【讨论】:

  • 严格来说,OP需要一个数组而不是std::vector。
  • 我认为零会被移到最后......如何缩小以适应帮助?
  • 您可以使用realloc“调整”数组的大小。但这只会让它变得更大。
  • @0A0D 但不是像 OP 要求的静态数组。 realloc 适用于以前使用 malloc(或类似名称)分配的 动态 数组。
【解决方案2】:

如果你必须调整数组的大小,为什么不简单地使用 std::vector。这个例子就是这样做的。

#include <vector>
#include <algorithm>

bool isZero (int i) 
{
    return i == 0;
}

int main()
{

    std::vector<int> myarray;

    myarray.push_back( 0 );
    myarray.push_back( 1 );
    myarray.push_back( 0 );
    myarray.push_back( 3 );
    myarray.push_back( 9 );

    std::vector<int>::iterator newIter = std::remove_if( myarray.begin() , myarray.end() , isZero);
    myarray.resize( newIter -  myarray.begin() );

    return 0;
}

【讨论】:

  • 我认为如果他甚至不知道如何编写一个 for 循环,那么混合向量可能有点过分了:)
  • 这就是为什么我没有混合 lambdas :)
  • 我不熟悉你在那里调用的函数 isZero。你能向我解释一下它在做什么以及这段代码是如何工作的吗?目前,我不确定如何实现这段代码以从数组中删除零。
  • @user1452373 std::remove_if 删除所有符合条件的元素。条件是您想要的 IsZero 函数。
  • @parapurarajkumar 如果remove 效果同样好,为什么还要使用remove_if
【解决方案3】:

如果不知道数组的内容,就无法知道有多少 值将非零,因此您的内存必须是动态的 分配。使用std::vector

std::vector<int> v;
std::copy_if(begin(array), end(array), std::back_inserter(v),
             [](int x) { return x != 0; });

如果您以 vector 开头,则可以使用擦除删除就地操作数据。

v.erase(std::remove(begin(v), end(v), 0), end(v));

如果你真的想努力做到这一点:

// count
auto non_zero_count = std::count_if(begin(array), end(array), 
                                    [](int x) { return x != 0;});
// allocate
int* new_array{new int[x]};
std::copy_if(begin(array), end(array), new_array,
             [](int x) { return x != 0; });

除非您知道所有输入,否则这里确实没有解决方案来达到固定大小的数组。

【讨论】:

    【解决方案4】:

    假设你有一个数组,你想删除数组中的 0 值并调整它的大小。

    int toResize[] = {4,3,2,0,8,7,9,0,5,4,7,0}; //12 elements
    vector<int>resized;
    vector<int>::iterator it;
    for(int i=0;i<12;i++){
    int check = toResize[i];
        if(check!=0){
         resized.push_back(check);
        }
    }
    
    for ( it=resized.begin() ; it < resized.end(); it++ )
    cout << " " << *it;
    

    如果您满意,请随时标记已回答的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-08
      • 2011-10-27
      • 2015-07-25
      • 2018-11-26
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多