How to “delete” a part of an array and keep the rest without running through it?
我尝试在C++中实现一个算法。
在伪代码中,有:w←w[0..e],其中w是字符数组,e是整数。基本上我想保留数组的一部分并丢弃其余部分。
为了使程序正常工作,我使用了一个for循环,在该循环中,我扫描原始数组直到e,然后将值复制到一个新数组中。
1 2 3 | char newArray[sizeIAlreadyKnow]; for (int i=0;i<e;i++) newArray[i] = w[i]; |
我知道这是不有效的;有没有办法避免遍历原始数组?我也不太熟悉向量。他们有这个功能吗?
提前谢谢你
您可以使用
你说得对,你真的应该使用向量!
这里有很多文档,在C++和STD容器上也有很多很好的教程(问问谷歌的一些)
考虑到您的问题,矢量可以做什么(创建一个副本)
1 2 3 | std::vector<char> myArray; // fill your array, do watherver work you want with it std::vector<char> newArray(&myArray[start], &myArray[end]); |
或者在你的情况下(调整大小)
1 2 3 | std::vector<char> myArray; // fill your array, do watherver work you want with it myArray.resize(e); |
这里列出的向量上的每个方法都有示例。阅读这些可能会对您的算法的实现有很大帮助。
如果您需要的话,可以使用vector(或任何其他std容器)上的algorithm部分进行更多操作(如排序)。
用C++ BuiTin数组或STD::vector输出框是不可能的。
在D编程语言中,这是可能的。如果向下滚动到下面链接中标记为"介绍切片"的部分,您将找到一个关于如何实现的解释。简而言之,没有垃圾收集是不可能做到的。不能在C++中通过在指针中间调用一个数组来释放一个数组。因此,如果您试图从数组中切出中间部分,然后丢弃旧指针,您将无法释放内存,并且您的程序将泄漏。
http://dlang.org/d-array-article.html
现在,虽然使用语言结构是不可能的,但它在许多其他方面是可能的。
当然,还有一个明显的问题,如amxx所述:您可以简单地将您想要的数组片段复制到一个新的数组或向量中。但是,如果你关心性能,这不是最好的方法。矢量构造器amxx使用的仍然会循环所有元素并复制它们,即使你看不到。
对于更有效的解决方案,有C++迭代器。如果您有一个函数要处理数组的一个子集,那么您可以让您的函数接受迭代器,而不是数组或向量。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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); |
还有字符串视图:http://en.cppreference.com/w/cpp/experimental/basic_string_视图
字符串视图是对字符串切片的非拥有引用,但您可以将其视为其切片所在的对象,而不必处理一对迭代器。在内部,它只存储指向原始字符串的指针。不过,需要注意的是,由于字符串视图是一个不拥有的引用,原始字符串的生存期必须比指向它的任何字符串视图的生存期都长。
同样的事情也可以用一个向量来完成,但是标准库中还没有这方面的内容(甚至字符串视图仍然是实验性的)。
我想你可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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