C++ 按索引向量排序
我有两个向量:向量和索引向量。如何使向量按索引向量排列?比如:C++ 按索引向量排序,c++,algorithm,C++,Algorithm,我有两个向量:向量和索引向量。如何使向量按索引向量排列?比如: Indexes 5 0 2 1 3 4 Values a b c d e f Values after operation b d c e f a 索引向量将始终包含范围[0,n],并且每个索引只包含一次。 我需要在适当的位置执行此操作,因为代码将在内存不足的设备上运行。 如何在C++中实现这一点?我可以使用C++ 11 你可以对向量进行排序,比较操作应该比较索引。当
Indexes 5 0 2 1 3 4
Values a b c d e f
Values after operation b d c e f a
索引向量将始终包含范围[0,n],并且每个索引只包含一次。
我需要在适当的位置执行此操作,因为代码将在内存不足的设备上运行。
如何在C++中实现这一点?我可以使用C++ 11 你可以对向量进行排序,比较操作应该比较索引。当然,当移动数据时,你也必须移动索引。 最后,您的索引将仅为0,1,…n-1,数据将位于相应的位置 作为实现说明:您可以将值和索引一起存储在一个结构中:
struct SortEntry
{
Data value;
size_t index;
};
并定义比较运算符以仅查看索引:
bool operator< (const SortEntry& lhs, const SortEntry& rhs)
{
return lhs.index < rhs.index;
}
你可以对向量排序,你的比较操作应该比较索引。当然,当移动数据时,你也必须移动索引 最后,您的索引将仅为0,1,…n-1,数据将位于相应的位置 作为实现说明:您可以将值和索引一起存储在一个结构中:
struct SortEntry
{
Data value;
size_t index;
};
并定义比较运算符以仅查看索引:
bool operator< (const SortEntry& lhs, const SortEntry& rhs)
{
return lhs.index < rhs.index;
}
它的复杂性很高,但对于较小的数值应该可以很好地工作
您也可以通过比较函数来实现C++的STL排序函数,如果您想在*Logn < /p>上
std::vector<int> indices = { 5, 0, 2, 1, 3, 4};
std::vector<char> values = {'a', 'b', 'c', 'd', 'e', 'f'};
for(size_t n = 0; n < indices.size(); ++n)
{
while(indices[n] != n)
{
std::swap(values[n], values[indices[n]]);
std::swap(indices[n], indices[indices[n]]);
}
}
它的复杂性很高,但对于较小的数值应该可以很好地工作
您也可以通过比较函数来实现C++的STL排序函数,如果您想在*Logn < /p>上
std::vector<int> indices = { 5, 0, 2, 1, 3, 4};
std::vector<char> values = {'a', 'b', 'c', 'd', 'e', 'f'};
for(size_t n = 0; n < indices.size(); ++n)
{
while(indices[n] != n)
{
std::swap(values[n], values[indices[n]]);
std::swap(indices[n], indices[indices[n]]);
}
}
编辑:
我想这应该是开着的,有人不同意吗
编辑:
我认为这应该是开着的,有人不同意吗?因为你知道你的索引数组是[0,N]的排列,你可以在线性时间和就地加上一个临时的工作循环。类似这样:
size_t indices[N];
data_t values[N];
for (size_t pos = 0; pos < N; ++pos) // \
{ // } this loops _over_ cycles
if (indices[pos] == pos) continue; // /
size_t i = pos;
const data_t tmp = values[pos];
while (true) // --> this loops _through_ one cycle
{
const size_t next = indices[i];
indices[i] = i;
values[i] = values[next];
if (next == pos) break;
i = next;
}
values[i] = tmp;
}
与每次使用swap相比,这种实现的优点是每个周期只需要使用一次临时变量
如果数据类型为“仅移动”,则如果所有赋值都由std::move包围,则此操作仍然有效。因为您知道索引数组是[0,N]的排列,所以可以在线性时间和就地加上一个临时工作循环来完成此操作。类似于:
size_t indices[N];
data_t values[N];
for (size_t pos = 0; pos < N; ++pos) // \
{ // } this loops _over_ cycles
if (indices[pos] == pos) continue; // /
size_t i = pos;
const data_t tmp = values[pos];
while (true) // --> this loops _through_ one cycle
{
const size_t next = indices[i];
indices[i] = i;
values[i] = values[next];
if (next == pos) break;
i = next;
}
values[i] = tmp;
}
与每次使用swap相比,这种实现的优点是每个周期只需要使用一次临时变量
如果数据类型为“仅移动”,则如果所有工作分配都由std::move包围,则此方法仍然有效。此解决方案将按时运行:
int tmp;
for(int i = 0; i < n; i++)
while(indexes[i] != i){
swap(values[i], values[indexes[i]]);
tmp = indexes[i];
swap(indexes[i], indexes[tmp]);
}
此解决方案将按时运行:
int tmp;
for(int i = 0; i < n; i++)
while(indexes[i] != i){
swap(values[i], values[indexes[i]]);
tmp = indexes[i];
swap(indexes[i], indexes[tmp]);
}
这将在没有任何错误的情况下按时运行。请检查它
这将在没有任何错误的情况下按时运行。请检查它
有一个问题是,比较运算符只给出值,而不是它们的索引,但是我需要将数据复制到sort entryWell,您有两种方法:1在开始时使数据处于适当的结构中;2使代码仅对索引进行排序,并且当作为排序过程的一部分移动索引时,移动应用程序还有一个问题是,比较运算符只给出值,而不是它们的索引。但是,我需要复制数据以对entryWell进行排序。您有两种方法:1在开始时使数据处于适当的结构中;2使代码仅对索引进行排序,以及在排序过程中移动索引时edure,也移动相应的数据。你考虑过了吗?你考虑过了吗?