要知道,我现在正在谈论C ++。
假设我有一个数组A = {4, 1, 5, 2, 3}
并在A_sorted = {1, 2, 3, 4, 5}
中对其进行排序。我想保留以下信息:现在元素e
(来自数组A)在排序数组A_sorted中的位置是什么?例如:A(5
)中索引为2的元素现在在A_sorted中具有索引4。
问题更像是:可以使用STL实现这一目标吗?
答案 0 :(得分:3)
没有现成的功能来实现这一目标,但有一些解决方法。例如,您可以保留一组用户定义的结构,这些结构也包含原始位置:
A = { {4,0}, {1,1}, {5,2}, {2,3}, {3,4}}
然后使用自定义比较器函数对其进行排序,该函数按值而不是原始索引进行排序。
A_sorted = {{1,1}, {2,3}, {3,4}, {4,0}, {5,2}}
答案 1 :(得分:3)
试试这个: 如果你想转换为vector:
int A[] = {4, 1, 5, 2, 3};
int A_sorted [] = {1, 2, 3, 4, 5};
std::vector<int> v(A_sorted, A_sorted + 5);
for (int i=0; i<5; i++)
{
std::vector<int>::iterator low = lower_bound (v.begin(), v.end(), A[i]);
std::cout << "Element: " << A[i] << " is at: " << distance(v.begin(), low) << std::endl;
}
如果你想处理原始数组:
int A[] = {4, 1, 5, 2, 3};
int A_sorted [] = {1, 2, 3, 4, 5};
for (int i=0; i<5; i++)
{
int* low = std::lower_bound (&A_sorted[0], &A_sorted[5], A[i]);
cout << "Element: " << A[i] << " is at: " << distance(&A_sorted[0], low) << endl;
}
答案 2 :(得分:2)
如果您无法修改A
中存储的内容,则可以创建索引数组并使用特殊谓词对其进行排序:
int A[] = {4, 1, 5, 2, 3};
size_t indices[] = {0, 1, 2, 3, 4};
bool sortBefore(size_t i, size_t j) {
return A[i] < A[j];
}
std::sort(indices, indices + 5, sortBefore);
然后,访问sorted_A[i]
作为A[indices[i]]
,或根据索引重新安排A
。 i -A
元素的新位置为std::find(indices, indices+5, i) - indices
。
答案 3 :(得分:1)
template<class T>
struct ValueWithIndex
{
T Value;
int index;
};
template<class T>
bool operator < (const ValueWithIndex<T>& v1, const ValueWithIndex<T>& v2)
{
return v1.value < v2.value;
}
template<class T> ValueWithIndex<T>
MakeValueWithIndex(const T& value, int index)
{
ValueWithIndex<T> ret;
ret.value = value;
ret.index = index;
return ret;
}
现在对容器ValueWithIndex
进行排序。有关原始索引的信息不会
迷路了。
int main()
{
std::vector<ValueWithIndex<int>> v;
for(int i = 0; i < n; ++i)
{
int value;
std::cin >> value;
v.push_back(MakeValueWithIndex(value, i));
}
std::sort(v.begin(), v.end());
}
答案 4 :(得分:1)
好的,索引通常会告诉你向量的第n个排序元素是什么。但是这样做会反过来,因此它会告诉你向量中的第n个元素是按排序顺序的第m个。
这是通过在非排序向量上创建索引向量来完成的。当然,您仍然可以创建排序副本或索引。
我们从谓词开始,其中&lt; b如果v [a]&lt; v并[b]
template< typename T >
class PredByIndex
{
private:
std::vector< T > const & theColl;
public:
PredByIndex( std::vector<T> const& coll ) : theColl( coll )
{
}
bool operator()( size_t i, size_t j ) const
{
return theColl[i] < theColl[j];
}
};
template< typename T >
void makeOrdered( std::vector< T > const& input, std::vector< size_t > & order )
{
order.clear();
size_t len = input.size();
order.reserve( len );
for( size_t i = 0; i < len; ++i )
{
order.push_back( i );
}
PredByIndex<T> pred( input );
std::sort( order.begin(), order.end(), pred );
}
现在“订单”将在有序集合中具有序数位置。
当然在C ++ 11中,谓词可以写成lambda表达式,而不是必须创建类PredByIndex。
我们还没有完成。我们现在有一个索引,而不是“在排序的向量中找到我”。但是我们可以transpose
我们的索引如下:
void transpose_index( std::vector< size_t > const & index,
std::vector< size_t > & trans )
{
// for this to work, index must contain each value from 0 to N-1 exactly once.
size_t size = index.size();
trans.resize( index.size() );
for( size_t i = 0; i < size; ++i )
{
assert( index[i] < size );
// for further assert, you could initialize all values of trans to size
// then as we go along, ensure they still hold that value before
// assigning
trans[ index[i] ] = i;
}
}
现在我们的转置索引为您提供了所需内容,转置本身为O(N)
在略有不同的数据示例中,如果输入为[ 5, 3, 11, 7, 2 ]
“已排序”订单为[ 2, 3, 5, 7, 11 ]
“索引”顺序是[4, 1, 0, 3, 2]
,即元素4是最小的,然后是元素1等。
“转置”顺序,我们填写
[ _, _, _, _, _ ]
[ _, _, _, _, 0 ]
[ _, 1, _, _, 0 ]
[ 2, 1, _, _, 0 ]
[ 2, 1, _, 3, 0 ]
[ 2, 1, 4, 3, 0 ]
这看起来像我们想要的。我们的原始数据5是排序数据中的位置2,3,位置1,位置11等。
答案 5 :(得分:0)
您可以使用find
搜索元素:
int *p1 = std::find(&A[0], &A[5], 5);
int *p2 = std::find(&A_sorted[0], &A_sorted[5], 5);
并使用距离显示索引:
int i1 = p1 - A;
int i2 = p2 - A_sorted;
i1和i2现在显示相应数组中的索引。