交换 std::list 中的相邻元素
Swap neighbouring elements in std::list
我想在std::list
中更改相邻元素的位置
列表和值的示例
A B C D E F G
3 2 1 2 1 3 2
我期望在排序后收到什么:
A B D C F E G
3 2 2 1 3 1 2
因此,简单的A > B
= 无事可做,但 C < D
= 交换它们并转到E
比较。
我不知道如何交换邻居元素。
所以,我想前进到1个步骤good
元素
您可以使用两个迭代器轻松完成此操作:
void biswap(std::list<int> &l)
{
if (l.size() < 2)
return;
auto it2 = l.begin();
auto it1 = it2++;
auto e = l.end();
for (;;)
{
if (*it1 < *it2)
std::swap(*it1, *it2);
it1 = it2++;
if (it2 == e)
return;
it1 = it2++;
if (it2 == e)
return;
}
}
现场示例
注意:如果您不使用 C++11,因此调用 size()
可能会产生很大的开销,您可以将其替换为以下内容(当然,将 auto
的所有用法替换为显式类型):
void biswap(std::list<int> &l)
{
auto it2 = l.begin();
auto e = l.end();
if (it2 == e)
return;
auto it1 = it2++;
if (it2 == e)
return;
for (;;)
// ... the rest as before
}
您可以使用标准算法std::adjacent_find
查找一对元素,首先<第二个元素,然后交换它们。>
例如
#include <iostream>
#include <algorithm>
#include <list>
#include <functional>
#include <iterator>
int main()
{
std::list<int> l = { 3, 2, 1, 2, 1, 3, 2 };
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
auto it = std::adjacent_find( l.begin(), l.end(), std::less<int>() );
if ( it != l.end() ) std::swap( *it, *std::next( it ) );
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
}
输出为
3 2 1 2 1 3 2
3 2 2 1 1 3 2
或者,如果您想在第一次<第二次处理所有这些情况,则可以使用以下代码>
#include <iostream>
#include <algorithm>
#include <list>
#include <functional>
#include <iterator>
int main()
{
std::list<int> l = { 3, 2, 1, 2, 1, 3, 2 };
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::list<int>::iterator it = l.begin();
while ( ( it = std::adjacent_find( it, l.end(), std::less<int>() ) ) != l.end() )
{
std::swap( *it, *std::next( it ) );
}
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
}
输出为
3 2 1 2 1 3 2
3 2 2 1 3 2 1
这给出了所需的结果,并按照您的要求切换了"好"元素的比较:
#include <list>
#include <iostream>
using namespace std;
template<typename Type>
void print(const list<Type> & l)
{
for (auto element : l) cout << element << " ";
cout << endl;
}
int main(int argc, const char *argv[])
{
list<int> l = {3,2,1,2,1,3,2};
print(l);
auto it = l.begin();
while(std::next(it) != l.end())
{
if (*it < *std::next(it))
{
std::swap(*it, *std::next(it));
++it;
}
++it;
}
print(l);
return 0;
}
执行结果:
3 2 1 2 1 3 2
3 2 2 1 3 1 2
如果您没有 C++11 支持,使用 2 个迭代器的简单 C++03 解决方案可能是:
#include <iostream>
#include <algorithm>
#include <list>
void swapNeighbours(std::list<int>& l) {
std::list<int>::iterator it = l.begin();
std::list<int>::iterator prev = it++;
while (prev != l.end() && it != l.end()) {
// swap if needed:
if (*prev < *it)
std::swap(*prev, *it);
// move 2 times forward:
if (++it == l.end())
break;
prev = it++;
}
}
然后(根据您的示例)如果您这样做:
void print(const std::list<int>& l) {
std::list<int>::const_iterator i;
for (i = l.begin(); i != l.end(); ++i) {
std::cout << *i << ' ';
}
std::cout << std::endl;
}
int main() {
std::list<int> l;
l.push_back(3); l.push_back(2); l.push_back(1); l.push_back(2);
l.push_back(1); l.push_back(3); l.push_back(2);
print(l);
swapNeighbours(l);
print(l);
}
然后对于:
A B C D E F G
3 2 1 2 1 3 2
将有以下比较: A < B
?(否) C < D
?(是的,掉期) E < F
?(是的,交换也是)产生输出:
3 2 2 1 3 1 2
如果您只想成对遍历并在第一个元素小于第二个元素时交换元素,那么您可以例如使用这样的std::adjacent_find
:
using std::swap;
for (auto it = std::begin(l); it != std::end(l); it = std::adjacent_find(it, std::end(l), std::less<int>{})) {
swap(*it, *std::next(it));
}
这将导致3 2 1 2 1 3 2
数字列表排列为:
3 2 2 1 3 2 1
但是,这与你的预期结果不同,3 2 2 1 3 1 2
我不明白你为什么不想像其他人一样交换最后一对1 2
?
如果您想要的是一个不稳定的排序模式,那么就没有简单的解决方案。相反,您必须对单个元素使用特殊处理。
相关文章:
- 使用std::transform将一个范围的元素添加到另一个范围中
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 我想访问std::unique_ptr中的一个特定元素
- 如何从存储在std::映射中的std::集中删除元素
- 缓存std::数组的选定元素,并在c++中自动保持其一致性
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 使用运算符 [] 引用 std::vector 上最后一个元素时出现问题<>
- 对的排序向量 (std::vector<pair<int, int>>) 按对的第一个元素搜索并更新第二个元素值
- 为什么在 std::map 上移动无法将元素从一个映射移动到另一个映射
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- std::矢量保存 只推送最后一个元素
- std::map:当元素不可默认构造时创建/替换元素
- 如何读/写或遍历 std::array 中的特定元素范围?
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- 为什么 std::p air 的大小与其元素的大小之和不同?
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 如何打印属于地图的一系列元素(std::p air<size_t,std::string>)(不是所有元素)
- 元素 std::vector <struct>的更有成效的段落
- 不能直接分配元素 std::array,它说没有运算符"="匹配
- 如何到达 2d std::vector 的第 N 个元素('std::vector< std::vector<T> >')?