面试题整理-从数组中删除指定元素

题目:

陈利人#Facebook面试题#这是一个编程题,动手做做才会有体会。给一个数组和一个值,从数组中删除这个指定的值的所有出现,

并且返回新的数组的长度。size_t remove_elem(T* array, size_t len, T elem) {}。


解题:

首先可以想到的是,用额外用一个数组。遇到不同的元素,就把此元素拷至额外的数组中。

实际上,很快就可以发现,用额外的数组与用当前这个数组,效果完全一样。

所以f = from;也就是直接指向当前数组的开头。

#include <iostream>
#include <iterator>
using namespace std;

template<class iterator, class T>
size_t xremove(iterator from, iterator to, const T &v) {
    if (from >= to) return -1;
    iterator b = from - 1, e = to, f = from;
    while(++b != e)
        if (*b != v) *f++ = *b;
    return f - from;
}

template<class T>
size_t xremove(T *a, const int n, const T &v) {
    if (!a || n <= 0) return -1;
    return xremove(a, a + n, v);
}

int main(void) {
    int array[] = {1,2,3,2,2,2,2,2,2,2,2,2,};
    int len = sizeof(array)/sizeof(*array);
    int length = xremove(array, len, 4);
    copy(array, array + length, ostream_iterator<int>(cout, " "));
    return 0;
}

可能现在,你觉得已经写好了。可以是很快又会发现。当数组中没有你想要删除的元素的时候,会出现重复拷贝的情况。也就是

会在原地拷贝。特别是当T类型是自定义类型。并且没有自己实现operator =运算符的时候,代价会比较高。


不要告诉我很多operator =的时候,都有

if (this != &a) { }才拷贝。当你没有写operator =的时候,系统会自动给你一个。谁知道那个是怎么工作的。


那么再把代码更改一下。由于考虑到iterator可能没有减法或者大于操作。那么只能再把代码再更改一下。

#include <iostream>
#include <iterator>
using namespace std;

template<class iterator, class T>
size_t xremove(iterator from, iterator to, const T &v) {
    if (from == to) return -1;
    iterator b = from, e = to, f = from;
    do {
        if (*b != v) {
            if (f < b) *f = *b;
            ++f;
        }
    } while (++b != e);
    return f - from;
}

template<class T>
size_t xremove(T *a, const int n, const T &v) {
    if (!a || n <= 0) return -1;
    return xremove(a, a + n, v);
}

int main(void) {
    int array[] = {1,2,3,2,2,2,2,2,2,2,2,2,};
    int len = sizeof(array)/sizeof(*array);
    int length = xremove(array, len, 4);
    copy(array, array + length, ostream_iterator<int>(cout, " "));
    cout << endl;
    return 0;
}


 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值