如何"delete"数组的一部分并保留其余部分而不运行它?

How to "delete" a part of an array and keep the rest without running through it?

本文关键字:余部 运行 保留 数组 delete 一部分 如何      更新时间:2023-10-16

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

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

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

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

我知道这样做效率不高;有没有一种方法可以避免遍历原始数组?此外,我对矢量也不是很熟悉。他们有这样的功能吗?

提前感谢

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

你是对的,你真的应该使用向量!

这里有很多文档,还有很多关于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);

这里列出的关于向量的每一种方法都有一个例子。阅读这些内容可能会对算法的实现有很大帮助。

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

使用C++内置数组或std::vector开箱即用是不可能的。

在D编程语言中,这是可能的。如果向下滚动到下面链接中标记为Introducing Slices的部分,您将找到关于如何实现这一功能的解释。简言之,如果没有垃圾收集,就无法做到这一点。在C++中,你不能通过对数组中间的指针调用delete来释放数组。因此,如果你试图从数组的中间切片,然后丢弃旧指针,你将无法释放内存,你的程序就会泄漏。

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);

还有类似字符串视图的内容:
http://en.cppreference.com/w/cpp/experimental/basic_string_view

string_view是对字符串切片的非拥有引用,但不必处理一对迭代器,您可以将其视为其切片所在的对象。在内部,它只存储指向原始字符串的指针。不过,需要注意的是,由于string_view是一个非拥有引用,因此原始字符串的生存期必须比指向它的任何string_vview的生存期都长

向量也可以做同样的事情,但标准库中还没有这方面的内容(甚至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