我基于这个问题的答案提出问题:
我有两个std :: vectors:
std::vector<int> time={5, 16, 4, 7};
std::vector<int> amplitude={10,17,8,16};
我想对向量进行排序以增加时间,所以最终它们将是:
TimeOrdered={4,5,7,16};
AmplitudeOrdered={8,10,16,17};
完成后,我想将两个有序向量添加到CERN ROOT TTree。我在网上寻找解决方案,并找到了上面的示例,其中最重要的答案是使用以下代码:
vector<int> data = {5, 16, 4, 7};
vector<int> index(data.size(), 0);
for (int i = 0 ; i != index.size() ; i++) {
index[i] = i;
}
sort(index.begin(), index.end(),[&](const int& a, const int& b) {
return (data[a] < data[b]);
}
);
for (int ii = 0 ; ii != index.size() ; ii++) {
cout << index[ii] << endl;
}
我喜欢它,因为它很简单,不需要太多的行,并且为我留了两个简单的向量,然后可以轻松地将其用于TTree。
因此,我尝试对其进行概括:
void TwoVectorSort(){
std::vector<int> data={5, 16, 4, 7};
std::vector<int> data2={10,17,8,16};
sort(data2.begin(), data2.end(),[&](const int& a, const int& b) {
return (data[a] < data[b]);
}
);
for (int ii = 0 ; ii != data2.size() ; ii++) {
std::cout <<data[ii]<<"\t"<< data2[ii]<<"\t"<< std::endl;//<<index[ii]
}
}
但是它不仅不起作用,而且每次都给我一些不同的东西。我正在使用.x TwoVectorSort.cpp +在ROOT 6.18 / 04上将其作为宏运行。
谁能告诉我为什么它不起作用以及最简单的解决方案是什么?我绝不是C ++专家,所以我希望答案不会太技术性!
提前致谢!
确实,您可以重用共享链接中的解决方案来解决问题。但是您需要继续构建index
向量(我相信没有必要修改time
或amplitude
向量)。
该index
载体被用于存储索引/位置的的time
排序从最小到最大矢量值,所以对于time={5, 16, 4, 7}
:
index[0]
将包含来自的最小值的索引time
(4
在位置2处),因此index[0]=2
index[1]
将包含的第二个最小值的索引time
(5
位于位置0),因此index[1]=0
等等
并且由于amplitude
的顺序是基于的,因此time
您可以index[pos]
在构建树时使用这两个向量:
time[index[pos]]
和amplitude[index[pos]]
带有更正的代码:
#include <iostream>
#include <vector>
#include <algorithm>
int main(){
std::vector<int> time={5, 16, 4, 7};
std::vector<int> amplitude={10,17,8,16};
std::vector<int> index(time.size(), 0);
for (int i = 0 ; i != index.size() ; i++) {
index[i] = i;
}
sort(index.begin(), index.end(),
[&](const int& a, const int& b) {
return (time[a] < time[b]);
}
);
std::cout << "Time \t Ampl \t idx" << std::endl;
for (int ii = 0 ; ii != index.size() ; ++ii) {
std::cout << time[index[ii]] << " \t " << amplitude[index[ii]] << " \t " << index[ii] << std::endl;
}
}
输出:
Time Ampl idx
4 8 2
5 10 0
7 16 3
16 17 1
但不仅不起作用,而且每次都给我一些不同的东西
发生这种情况是因为lambda接收的参数来自,data2={10,17,8,16}
并且这些值被用作索引来访问处的data
向量return (data[a] < data[b])
。它引起了一些随机排序,因为它正在访问向量的范围之外并从内存中读取垃圾(因此出现了随机行为)。
非常感谢你的帮助。之前我从未见过lambda的语法,并且已经查看了您提供的链接,但是我发现它非常技术性。您介意以一种非常简单的方式向我解释吗?它到底是做什么的,它是如何做到的?再次非常感谢!
(yw!)一种简单的方法(虽然不精确)是:lambda表达式是一种在函数内定义函数的方法。std :: sort接收3个参数:前2个是向量中的元素,第3个是用于比较前2个元素的函数(即函子)。使用lambda可以内联比较函数,避免在外部创建函数。在C ++ 11中的lambda表达式中,您会找到有关lambda的更好解释。。
好的,该链接非常有用,谢谢!因此,请尝试并真正理解:lambda将当前作用域中的所有变量放入其捕获列表[&]中,启动两个常量整数变量作为参数(const int&a,const int&b)并返回...什么?时间[a] <时间[b]是不是很麻烦?lambda如何知道要使用的a和b值?真的是在尝试学习新东西!再次感谢 :)
这些参数与std :: sort(为初学者解释的排序)有关。如果您使用的是函数(使用相同的代码,但使用function),则将是相同的,因为sort每次都会从向量中调用带有两个参数的lambda / function。lambda和custom函数都需要返回一个布尔值,因为std :: sort用来比较每对元素,以便可以对整个结构进行排序。
请忽略上面代码段的输出,因为它只是为了说明使用lambda排序和使用函数之间的区别。您可以将比较函数更改为大于,它将以相反的方式排序。希望对您有所帮助!如果您有与最初的问题无关的疑问,请不要犹豫打开单独的问题。