如何在c++中快速交换列表和向量等容器中的对象
How to quickly swap object in containers such as list and vector in c++
我想知道C++容器(如list和vector)中的快速交换方法是什么,因为我还没有找到任何内置的交换函数。仅供参考,我想交换对象,而不是整个列表。
例如,假设我们有这样的int序列3 2 4 5,并且它们存储在列表容器(stl)中,我想交换2和4。这是我想出的一个愚蠢的方法:
list<int> numbers;
numbers.push_back(3);
numbers.push_back(2);
numbers.push_back(4);
numbers.push_back(5);
list<int>::iterator item;
item=numbers.begin();
advance(item,2);
int key = *item;
advance(item,-1);
numbers.insert(item,key);
advance(item,1);
numbers.erase(item);
所以,简单地说,我在这里所做的只是"复制、插入和删除",我之所以这么做,是因为我听说列表容器在插入和删除元素方面非常有效,但我确信应该有更好的算法。此外,我还听说有一种与指针相关的常量时间交换方法,所以有人知道它吗
谢谢你帮忙。
您想要std::swap
:
list<int>::iterator item1 = numbers.begin();
++item1;
list<int>::iterator item2 = item1;
++item2;
std::swap(*item1, *item2);
使用iter_swap
将两个迭代器指向的元素交换到列表中。这样可以交换数据,而不是节点,但这很容易。
#include <list>
#include <iostream>
int main() {
std::list<int> numbers;
numbers.push_back(3);
numbers.push_back(2);
numbers.push_back(4);
numbers.push_back(5);
auto first = std::next(numbers.begin(), 2);
auto second = std::next(numbers.begin(), 1);
std::iter_swap(first, second);
for(int& v : numbers)
std::cout << v << ' ';
}
http://coliru.stacked-crooked.com/view?id=a89b3b1ae9400367b6ff194d1b504e58-f674c1a6d04c632b71a62362cfcfc51
如果你想交换节点而不是元素,你可以使用list::splice
,尽管它有点欺骗:
int main() {
std::list<int> numbers;
numbers.push_back(3);
numbers.push_back(2);
numbers.push_back(4);
numbers.push_back(5);
std::list<int> temporary;
auto move_from = std::next(numbers.begin(), 2);
temporary.splice(temporary.begin(), numbers, move_from, std::next(move_from));
auto move_to = std::next(numbers.begin(), 1);
numbers.splice(move_to, temporary);
for(int& v : numbers)
std::cout << v << ' ';
}
您可能正在寻找一种在列表中移动节点的方法,而无需复制实际元素。您可以使用list::splice来完成此操作。当然,对于不是基于节点的向量来说,并没有类似的可能。
类似这样的东西:
list<int>::iterator to = numbers.begin();
++to;
list<int>::iterator which = to;
++which;
numbers.splice(to, numbers, which);
使用swap
怎么样?
using std::swap;
swap(numbers[1], numbers[2]);
其将使用CCD_ 5或ADL来确定适当的交换函数(如果存在为自变量定义的交换函数)。
正如@MooingDuck正确指出的那样,std::list
要求您使用迭代器。
std::iter_swap(numbers.begin()+1, numbers.begin()+2);
你也可以使用
using std::swap;
std::list<int>::iterator item(numbers.begin());
std::advance(item, 1);
std::list<int>::iterator other(item);
std::advance(other, 1);
swap(*item, *other);
或
using std::swap;
swap(*std::next(numbers.begin(), 1), *std::next(numbers.begin(), 2));
或
std::iter_swap(std::next(numbers.begin(), 1), std::next(numbers.begin(), 2));
使用std::swap(),
int reverse(std::list<int>& list){
int exchange = 0;
int move = 0;
int distance_lo = 0;
int distance_hi = 0;
std::list<int>::iterator it_lo = list.begin();
std::list<int>::iterator it_hi = --list.end();
while (1) {
it_lo = list.begin();
it_hi = --list.end();
std::advance(it_lo, move);
std::advance(it_hi, -move);
distance_lo = std::distance(list.begin(), it_lo);
distance_hi = std::distance(list.begin(), it_hi);
if (distance_lo < distance_hi) {
std::swap(*it_lo, *it_hi);
exchange++;
} else {
break;
}
move++;
}
return exchange; }
使用std::list::splice(),
int reverse(std::list<int>& list) {
int exchange = 0;
int move = 0;
int distance_lo = 0;
int distance_hi = 0;
std::list<int>::iterator it_lo = list.begin();
std::list<int>::iterator it_hi = --list.end();
while (1) {
it_lo = list.begin();
it_hi = --list.end();
std::advance(it_lo, move);
std::advance(it_hi, -move);
distance_lo = std::distance(list.begin(), it_lo);
distance_hi = std::distance(list.begin(), it_hi);
if (distance_lo < distance_hi) {
std::list<int> tmp;
tmp.splice(tmp.begin(), list, it_lo);
tmp.splice(std::next(tmp.begin(),1), list, it_hi);
it_lo = list.begin();
it_hi = --list.end();
std::advance(it_lo, move); //insert before it_lo
std::advance(it_hi, -move);
std::advance(it_hi, 1); //insert after it_hi
list.splice(it_lo, tmp, std::next(tmp.begin(),1));
list.splice(it_hi, tmp, tmp.begin());
exchange++;
} else {
break;
}
move++;
}
return exchange; }
希望它能帮助你:)
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 迭代时从向量和内存中删除对象
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- 如何创建从同一类继承的不同对象的向量
- 在nlohmann json中,如何将嵌套对象的数组转换为嵌套结构的向量
- 从多个源构造一个对象,包括一个对象向量
- 在C 中,是否有可能在不兼容类型的std ::向量对象之间传输不同类型的缓冲区
- 将向量对象存储在共享指针投掷错误中
- E0312,C2664尝试将向量对象作为函数参数传递时错误
- 相对于向量对象的两个成员,找到两个向量的相交的有效方法
- 将数据从文件读取到向量对象
- C 向量对象访问
- 向量对象声明后的括号是什么意思
- 2向量对象指向相同的分配内存
- 如何返回向量对象
- 传递单个或向量对象时没有重载函数的实例
- 指向数组和向量对象的指针
- 向量对象库,可以存储其他对象类型的对象
- 如何从另一个向量/对象集构造新的向量/指针集