如何以适合C++的方式删​​除数组中最小和最大的元素?

bao*_*bao 5 c++

假设我有一个int数组,我想调用一个函数来删除最小和最大的值.通过删除我的意思是如果我的初始数组长度为7个元素,则新数组有5个元素.其余元素的顺序无关紧要.我想出了一些方法来做到这一点,但我不确定哪一个是C++"做"它的方式,如果这是有道理的.

我现在拥有的是我使用std :: sort来对我的数组进行排序,然后我使用for循环从第二个元素开始复制结果,并从倒数第二个元素停止到具有适当大小的新数组.我应该如何返回阵列?

我无法返回新创建的数组,因为它是函数的局部变量.我可以将新数组作为参数传递给函数,但这不是更老的,C风格的方式吗?我也可以使用std :: vector,但是我必须将数组包装在一个向量中然后打开它(数字需要保留在一个int数组中).好像有点矫枉过正,不是吗?

我来自Python背景,我只是想知道在C++中使用它的更合适的方法是什么.

Mac*_*ehl 8

如果数字必须保持在一个整数数组中并且顺序无关紧要,我会这样做:

void MoveHiLoToEnd(int orig[], int size)
{
    int* last = orig + size - 1;
    int* maxp = std::max_element(orig, orig + size);
    std::iter_swap(maxp, last);
    int* minp = std::min_element(orig, orig + size - 1);
    std::iter_swap(minp, last - 1);

    //now the original array contains max and min elements moved.
    //to the end. You can ignore them or copy elements except
    //those last two to a new array, if really necessary.
}
Run Code Online (Sandbox Code Playgroud)

签名

int* MoveHiLoToEnd(int* begin, int* end);
Run Code Online (Sandbox Code Playgroud)

更多的是C++库样式,它可以更改为模板

template<typename ForwardIter>
ForwardIter RemoveHiLo(ForwardIter begin, ForwardIter end);
Run Code Online (Sandbox Code Playgroud)

将迭代器返回到旧的min元素(通过新的截断集合),但我怀疑它是否值得.这将需要调用中的不同(我认为不太方便)参数.

编辑

对不起模板的想法很糟糕.事情变得复杂了.你必须要求双向迭代器(这使得模板的通用性低于前向模板.对于min和max_element forward足够了)

template<typename BidirectionalIterator>
BidirectionalIterator RemoveHiLo(BidirectionalIterator begin, BidirectionalIterator end);
Run Code Online (Sandbox Code Playgroud)

或非标准输入参数,因为您需要最后一个元素的迭代器.


Jam*_*ran 7

忘记数组并使用它std::vector<int>.

using std::vector;

vector<int> WithoutHiLo(vector<int> orig)
{
     std::sort(orig.begin(), orig.end());
     vector<int> newVec = vector(orig.size());
     std:copy(&orig[1], &orig[orig.size()-1], &newVec[0]);
     return newVec;
}
Run Code Online (Sandbox Code Playgroud)

更新(每条评论):

vector<int> WithoutHiLo(vector<int> orig)
{
     std::sort(orig.begin(), orig.end());
     return vector(&orig[1], &orig[orig.size()-1]);
}
Run Code Online (Sandbox Code Playgroud)

如果你真的需要一个输入数组:

vector<int> WithoutHiLo(int orig[], int size)
{
     std::sort(&orig[0], &orig[size]);
     vector<int> newVec = vector(size);
     std:copy(&orig[1], &orig[size-1], &newVec[0]);
     return newVec;
}
Run Code Online (Sandbox Code Playgroud)

  • -1."忘记数组"你知道,std :: vector的所有好处都不是免费的 - 涉及开销和额外的内存.而且你不需要排序.并且您可以在没有另一个的情况下修改向量(使用最后两个值交换最小值/最大值,然后使用size() - 2调整向量的大小).并且您按值返回向量,这可能涉及复制构造函数.不管你怎么看它,不好的建议,IMO ...... (2认同)
  • @SigTerm:除了最后一部分,我同意一切.NRVO消除了这种开销. (2认同)