如何"delete"数组的一部分并保留其余部分而不运行它?
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,然后将值复制到一个新数组中。
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
- 运行同一解决方案的另一个项目的项目
- CMake-按正确顺序将项目与C运行时对象文件链接
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 代码在main()中运行,但在函数中出现错误
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何在运行中期切换GTK CSS style_context
- 如何在MS Visual Studio 2019中运行QT UI
- 如何通过cpp程序运行shell脚本
- IPC使用多个管道和分支进程来运行Python程序
- 删除指向指针的指针是运行时错误吗
- 如何用参数值调用函数(仅在运行时已知)
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- c++中的指针和运行时错误
- 在C应用程序中运行C++(带有STL)函数
- 运行程序时出现问题
- 控制允许动态运行c++的并发操作数
- 无法获取菜单选择以运行函数.C++