Reputation: 71
We have an unsorted array, need to print the position of each element assuming that it gets sorted.
e.g.: we have an array.
arr[] = {3, 2, 6, 1, 4}
//index: 1 2 3 4 5 Index of elements 1-based
//Sorted {1, 2, 3, 4, 6} List after sorting
//index: 4 2 1 5 3 Index of elements from original array
it should print
4 2 1 5 3
Upvotes: 7
Views: 5173
Reputation: 217275
You may use the following:
template <typename T>
std::vector<std::size_t> compute_ordered_indices(const std::vector<T>& v)
{
std::vector<std::size_t> indices(v.size());
std::iota(indices.begin(), indices.end(), 0u);
std::sort(indices.begin(), indices.end(), [&](int lhs, int rhs) {
return v[lhs] < v[rhs];
});
return indices;
}
Upvotes: 0
Reputation: 30489
Store the data and index of array element as a pair and sort the array of pairs. Now print only the index part.
// Original array
int arr[] = {3, 2, 6, 4};
// Size of original array
const int sz = static_cast<int>(sizeof arr / sizeof arr[0]);
// Array of pair {.first = item, .second = 1-based index
std::vector< pair<int, int> > vp(sz); // std::array if size is fixed
for(int i = 0; i < sz; ++i) vp[i] = make_pair(arr[i], i + 1); /* Can be done in a more fancy way using std::transform + lambda */
// Sort the array, original array remains unchanged
std::sort(vp.begin(), vp.end());
// Print the result
for(int i = 0; i < sz; ++i) cout << ' ' << vp[i].second;
Time complexity of the code: O(N log N) where N is the number of elements in the array
From you comment as the value of N is large and all numbers are distinct, you can use the following snippet
int maxn = maximum value of a number;
int positions[maxn] = {0}; // Or choose a sparse array with constant update time
int arr[] = {3, 2, 6, 4};
const int sz = static_cast<int>(sizeof arr / sizeof arr[0]);
for(int i = 0; i < sz; ++i) {
assert( arr[i] >= 0 );
position[ arr[i] ] = i + 1;
}
for(int i = 0; i < maxn; ++i) {
if(position[i]) cout << ' ' << position[i];
}
Time complexity of the code: O(N) where N is the maximum value of the number
Upvotes: 4
Reputation: 4191
I don't know if it is the most efficient way but I'd create an array of nodes
. Each node
having value
and pos
.Then, sort according to value from which you can retrieve the position.
struct node{
int value;
int pos;
}
As I said, it will work but I doubt it is the most efficient way
Upvotes: 1
Reputation: 4100
Sort the array {1, 2, 3, ..., N}
in parallel with the given array. So in your example, {3, 2, 6, 4}
would be sorted, with every swap affecting that array and the array {1, 2, 3, 4}
. The final result would be {2, 3, 4, 6}
for the first array and {2, 1, 4, 3}
for the second; the latter array is the answer to your question.
In case that isn't clear, here's a longer example:
5 2 1 4 3
1 2 3 4 5
2 5 1 4 3
2 1 3 4 5
2 1 5 4 3
2 3 1 4 5
2 1 4 5 3
2 3 4 1 5
2 1 4 3 5
2 3 4 5 1
2 1 3 4 5
2 3 5 4 1
1 2 3 4 5
3 2 5 4 1
I used bubble sort :-) to sort the top row, and just swapped the bottom row in parallel with the top row. But the idea should work with any sorting method: just manipulate the bottom row in parallel with the operations (swaps or whatever) you are performing on the top row.
Upvotes: 6
Reputation: 1376
I don't know C++, so I cannot give you the exact code, but the below pseudo code should work.
1. Given input array
2. Take another empty array of equal length (This will be the output array of positions)
3. Fill the output array with zero (initially all values will be zero in the array)
4. while (output array does not contain zero)
a. loop through input array and find maximum number in it.
b. get the position of maximum number from input array and set it at the same position in output array
c. ignore the element in input array ,if corresponding index in output array is not zero (if it is not zero, then it means index is already filled up)
5. Repeat setps a,b and c until all the elements in output array becomes non zero
The complexity of this algorithm is O(n2). I did not find a better way than this. Please let me know, if you have any queries.
Upvotes: 0
Reputation: 11284
You can create an array perm
, which hold the index of the first array arr
, and sort this perm
array based on the value of arr
int arr[] = {3, 2, 6, 4};
int compare (const void * a, const void * b) {
int diff = arr[*(int*)a] - arr[*(int*)b];
return diff;
}
int main(void) {
int perm[4], i;
for (i = 0 ; i != 4 ; i++) {
perm[i] = i ;
}
qsort (perm, 4, sizeof(int), compare);
for (i = 0 ; i != 4 ; i++) {
printf("%d ", perm[i] + 1);
}
return 0;
}
Output:
2 1 4 3
Upvotes: 3