我想创建一个程序来生成在将数组更改为另一个数组期间交换元素的步骤(例如:从{0,1,2}到{0,2,1},步骤为1< - > 2,这意味着交换元素1和元素2的位置,以A = {0,3,2}和B = {2,1}为例,我的原始概念如下:
>在按顺序排序A的过程中,获取交换元素的步骤
>按顺序排序B中的元素交换步骤
>交换A中的元素,从按照步骤排序A开始,然后按照相反顺序对B进行排序
这是我试过的代码:
#include <stdlib.h> #include <functional> #include <vector> int main(){ std::function<bool(int,int)> f=[](int a,int b){ if(a>=b) printf("%d<->%d\n",a,b); return a<b; }; std::vector<int> a={0,2}; std::sort(a.begin(),a.end(),f); printf("---\n"); std::vector<int> b={2,1}; std::sort(b.begin(),b.end(),f); return 0; }
输出:
1<->0 //step to sort A 3<->1 2<->1 --- 3<->0 //step to sort B 3<->2 1<->0
所以从0,2改为2,1的步骤应该是:
1<->0 3<->1 2<->1 1<->0 3<->2 3<->0
但是当我按照这个步骤:
0,2 1,2 3,1 3,0 2,3
结果是2,3而不是2,为什么?我的概念是否产生了错误的步骤?如果是这样,还有其他方法来生成通过交换位置将数组更改为另一个数组的步骤吗?
解决方法
问题是,每次进行比较时都打印“交换”,并且两个值的顺序不正确,这可能不正确,std :: sort算法可能会在没有交换的情况下进行检查.您可以使用自定义Int结构来测试:
struct Int { Int(int v) : v_(v) { } Int(const Int&) = default; Int& operator=(const Int& o) { std::cout << v_ << " <- " << o.v_ << '\n'; v_ = o.v_; return *this; } int v_; }; bool operator<(const Int& lhs,const Int& rhs) { return lhs.v_ < rhs.v_; }
然后:
int main(){ std::vector<Int> a{0,2}; std::cout << "Sorting A:\n"; std::sort(a.begin(),a.end()); std::cout << '\n'; std::vector<Int> b={2,1}; std::cout << "Sorting B:\n"; std::sort(b.begin(),b.end()); return 0; }
输出是:
Sorting A: Sorting B: 1 <- 1 0 <- 2 3 <- 3 2 <- 0 2 <- 3 3 <- 3 3 <- 2 1 <- 3 3 <- 2 2 <- 1
这为您提供了各种分配 – 请注意,std :: sort实现可以针对这样的小范围进行优化,这意味着您不需要交换(例如,在上面,对于B,您可以将1,2和3交换在一起) ).
所以你需要做的是(没有无用的< -a):
2 <-> 3 2 -> 1 3 -> 2 1 -> 3 0 <-> 2
然后你需要在二进制交换中转换它:
2 <-> 3 2 <-> 1 1 <-> 3 0 <-> 2
如果你想直接获得二进制交换,你会变得更丑陋(希望你的计算机对这个UB很温和)并且:
struct Int { Int(int v) : v_(v) { } Int(const Int&) = default; Int& operator=(const Int& o) { if (v_ != o.v_) std::cout << v_ << " <-> " << o.v_ << '\n'; std::swap(v_,o.v_); return *this; } mutable int v_; };
输出:
Sorting A: Sorting B: 2 <-> 3 0 <-> 2 1 <-> 3 1 <-> 2
联合:
2 <-> 3 1 <-> 2 1 <-> 3 0 <-> 2