根据索引向量对向量重新排序 - 更新
Reorder vector according to a vector of indices - update
这是对之前关于就地重新排序的问题的更新 关于索引向量有一些混淆。调用要重新排序的向量 vA,以及索引 vI 的向量,则 vA 应按此顺序重新排序,vA[vI[0]]、vA[vI[1]]、vA[vI[2]、...一个示例用法是将 vI 初始化为一组 vA.size() 索引,从 0 到 vA.size()-1,然后根据 vA 对 vI 进行排序(使用 vA[vI[...]] 进行比较)。然后可以使用重新排序函数根据 vI 对 vA 进行排序。
将初始 vA 视为已排序 vA 的排列。根据 vA 对 vI 进行排序后,然后根据 vI 对 vA 进行重新排序"取消排列"vA,返回到排序的排列。使用下面显示的示例函数,对 vA 进行重新排序也会将 vI 重新排序回其初始化状态(0 到 vA.size()-1)。
下面的示例显示了一个名为reorderfail()的非工作版本,后跟一个名为reorder()的工作版本。这两个函数都将 vI 返回到其原始状态 0 到 vA.size()-1,但 reorderfail() 无法正确对 vA 进行重新排序,因为它缺少"取消排列"vA 所需的间接级别。
#include <algorithm>
#include <vector>
using namespace std;
template <class T>
void reorderfail(vector<T>& vA, vector<size_t>& vI)
{
size_t i, j;
for(i = 0; i < vA.size(); i++ ){
while(i != (j = vI[i])){
swap(vA[i], vA[j]);
swap(vI[i], vI[j]);
}
}
}
template <class T>
void reorder(vector<T>& vA, vector<size_t>& vI)
{
size_t i, j, k;
for(i = 0; i < vA.size(); i++){
while(i != (j = vI[i])){
k = vI[j];
swap(vA[j], vA[k]);
swap(vI[i], vI[j]);
}
}
}
int main( )
{
char A[] = { 'b', 'c', 'a' };
size_t I[] = { 2 , 0 , 1 }; // order should be A[2] A[0] A[1]
size_t size = sizeof(A) / sizeof(*A);
vector<char> vA(size);
vector<size_t> vI(size);
vA.assign(A, A + size);
vI.assign(I, I + size);
reorderfail(vA, vI); // returns vA = {'c', 'a', 'b'};
vA.assign(A, A + size);
vI.assign(I, I + size);
reorder(vA, vI); // returns vA = {'a', 'b', 'c'};
return(0);
}
移动数据而不是交换数据的工作重新排序版本。这个例子可能更容易解释。每个排列都是一组"循环"。通过撤消循环来重新排序。假设有 8 个元素,并且 vI 包含所需的顺序。我将索引 i 放在 vI 上方:
i : { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 }
vI[i] = { 5 , 7 , 0 , 3 , 6 , 2 , 4 , 1 }
周期 1: vI[0] == 5, vI[5] == 2, vI[2] == 0。
周期 2: vi[1] == 7, vi[7] == 1。
周期 3: vI[3] == 3.
周期 4: vI[4] == 6, vi[6] == 4.
撤消循环 1, t = vA[0], vA[0] = vA[5], vA[5] = vA[2], vA[2] = t。
撤消循环 2, t = vA[1], vA[1] = vA[7], vA[7] = t.
撤消周期 3,无需更正
撤消周期 4, t = vA[4], vA[4] = vA[6], vA[6] = t.
每次在 vA[k] 中存储值时,vI[k] 都设置为 k 以指示 vA[k] 已排序。
template <class T>
void reorder(vector<T>& vA, vector<size_t>& vI)
{
size_t i, j, k;
T t;
for(i = 0; i < vA.size(); i++){
if(i != vI[i]){
t = vA[i];
k = i;
while(i != (j = vI[k])){
// every move places a value in it's final location
vA[k] = vA[j];
vI[k] = k;
k = j;
}
vA[k] = t;
vI[k] = k;
}
}
}
- 将结构向量排序为子组
- C++数组与向量排序(在我的情况下,向量比数组慢~2.5倍(无优化))
- 如何在对向量排序后更改索引值?c++
- C++向量排序给出0作为输出
- 将许多向量排序在一起
- 根据一个向量对多个向量排序
- 编译错误向量排序和联合
- C++我自己的函数进行向量排序
- 将字符串的向量排序为日期"yyyymmdd"
- C++ 通过使用旧向量进行预排序来改进向量排序
- C 向量排序 .h .cpp中的单独文件
- 向量排序-c++
- 将向量排序到一个无序映射c++11中
- 向量的向量排序
- c++向量排序方法编译失败,返回预期表达式
- 如何对bitset向量排序
- 向量排序的基础上只有先
- 我如何以相同的方式对两个向量排序,而条件只使用其中一个向量
- 列表排序和结构体向量排序之间的性能差距.c++
- 如何基于第二个字符串对字符串向量的向量排序