如何“删除”一个数组的一部分并保持其余部分而不通过它?

时间:2015-02-12 02:52:28

标签: c++ arrays

我正在尝试用C ++实现一个算法。

在伪代码中,有:w←w [0..e],其中w是字符数组,e是整数。基本上我想保留阵列的一部分并丢弃其余部分。

为了使程序正常工作,我使用了for循环,我在原始数组中扫描到e,然后将值复制到新数组中。

char newArray[sizeIAlreadyKnow];
    for (int i=0;i<e;i++) 
        newArray[i] = w[i];

我知道这不高效;有没有办法避免迭代原始数组? 我也不太熟悉矢量。他们有这个功能吗?

提前谢谢

3 个答案:

答案 0 :(得分:2)

您可以使用std::string::resize。基本思想是使用std::string而不是char的原始数组。相应地,使用std::vector<T>而不是T的原始数组,事情也变得更加容易和安全。

答案 1 :(得分:1)

你是对的,你应该真的使用载体!

有很多文档可用here,还有很多关于c ++和std容器的好教程(请谷歌查询其中一些)

保留你的问题,载体可以做什么(创建副本)

std::vector<char> myArray;
// fill your array, do watherver work you want with it
std::vector<char> newArray(&myArray[start], &myArray[end]);

或在你的情况下(调整大小)

std::vector<char> myArray;
// fill your array, do watherver work you want with it
myArray.resize(e);

here中列出的向量中的每一个方法都带有例子。阅读这些内容可能对您的算法实施有很大帮助。

如果您需要,可以使用向量(或任何其他标准容器)上的algorithm section进行更多操作(例如排序)

答案 2 :(得分:0)

C ++内置数组或开箱即用的std :: vector无法满足您的要求。

在D编程语言中,它是可能的。如果您向下滚动到下面链接中标有介绍切片的部分,您将找到有关其可能性的说明。简而言之,它不能在没有垃圾收集的情况下完成。你不能通过在指向它中间的指针上调用delete来释放C ++中的数组。因此,如果你试图从数组中间切片,然后抛弃旧指针,你将无法释放内存,并且你的程序会泄漏。

<强> http://dlang.org/d-array-article.html

现在,尽管使用语言结构是不可能的,但它可以通过其他方式实现。

当然,有明显的,如Amxx所述:您可以简单地将所需数组的片段复制到新的数组或向量中。但是,如果你关注性能,这不是最好的方法。矢量构造函数Amxx正在使用仍会遍历所有元素并复制它们,即使你看不到它。

对于更有效的解决方案,有 C ++迭代器。如果你有一个想要处理数组子集的函数,你可以使你的函数接受迭代器而不是数组或向量。

例如:

int sumElements(vector<int>::iterator first, vector<int>::iterator last)
{
    int sum = 0;

    for( ; first != last; ++first)
        sum += *first;

    return sum;
}

vector<int> numbers;

for(int i = 0; i < 100; ++i)
    numbers.push_back(i);

int sum = sumElements(numbers.begin() + 10, numbers.begin() + 20);

还有 string_view 之类的东西:
http://en.cppreference.com/w/cpp/experimental/basic_string_view

string_view是对字符串切片的非拥有引用,但是不必处理一对迭代器,您可以像对待它一样对待它。在内部,它只存储指向原始字符串的指针。但需要注意的是,由于string_view是一个非拥有引用,原始字符串的生命周期必须比指向它的任何string_view的寿命长。

同样的事情也可以用矢量完成,但标准库中没有任何东西(甚至string_view仍然是实验性的)。

我想你可以这样做:

template<class T>
class vector_view
{
    vector<T>::iterator first;
    vector<T>::iterator last;
public:
    vector_view(vector<T>::iterator first, vector<T>::iterator last)
        : first(first), last(last) { }

    const T& operator[](size_t i) const {
        assert(first + i < last);
        return *(first + i)
    }

    size_t size() const {
        return last - first;
    }
};

vector<int> numbers;
// ... init numbers with 100 numbers

vector_view<int> vv(numbers.begin() + 5, numbers.begin() + 32);

int number = vv[10];

我可能会坚持使用向量和迭代器来保持简单,但是你有它。

编辑:与C ++范围的提案中讨论了与上述类似的想法:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4128.html