我有两个向量:向量和索引向量。如何通过索引向量来排列向量?像:
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 :(得分:3)
由于您知道索引数组是[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()
包围,这仍然有效。
答案 1 :(得分:1)
for(int i=0;i<=indexes.size();++i)
for(int j=i+1;j<=indexes.size();++j)
if(indexes[i] > indexes[j] )
swap(indexes[i],indexes[j]),
swap(values[i],values[j]);
这是O(N²)复杂度,但应该在小数值上正常工作。
如果你想要O(N * logN)
,你也可以将比较函数传递给C ++ STL排序函数答案 2 :(得分:1)
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]]);
}
}
编辑:
我认为这应该是O(n),有人不同意吗?
答案 3 :(得分:0)
您可以对矢量进行排序,您的比较操作应该比较索引。当然,在移动数据时,你也必须移动索引。
最后,您的索引将只是0,1,...(n-1),数据将位于相应的位置。
作为实施说明:您可以将值和索引存储在一个结构中:
struct SortEntry
{
Data value;
size_t index;
};
并定义比较运算符以仅查看索引:
bool operator< (const SortEntry& lhs, const SortEntry& rhs)
{
return lhs.index < rhs.index;
}
答案 4 :(得分:0)
此解决方案在O(n)时间内运行:
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]);
}
答案 5 :(得分:0)
这将在O(n)时间内运行,没有任何错误。请在ideone
上查看int main(int argc, char *argv[])
{
int indexes[6]={2,3,5,1,0,4};
char values[6]={'a','b','c','d','e','f'};
int result[sizeof(indexes)/4]; //creating array of size indexes or values
int a,i;
for( i=0;i<(sizeof(indexes)/4);i++)
{
a=indexes[i]; //saving the index value at i of array indexes
result[a]=values[i]; //saving the result in result array
}
for ( i=0;i<(sizeof(indexes)/4);i++)
printf("%c",result[i]); //printing the result
system("PAUSE");
return 0;
}