Reputation: 6316
I have an array A:
A = [10 11 3 15 8 7]
index = 0 1 2 3 4 5
I want to sort this array.After sorting I want the information of old index.For this I can create a structure like this.
struct VnI{
int value;
int index;
};
sorting the array of structure with respect to value solve my problem.But I want to know that is it possible to solve this using sort or any other function in C++11.
I have tried this way:
struct VnI{
int V;
int I;
};
bool comparator(VnI x,VnI y){
if(x.V < y.V)
return true;
return false;
}
int maximumGap(const vector<int> &A) {
vector<VnI> B;
for(int i = 0;i < A.size();i++){
B[i].I = i;
B[i].V = A[i];
}
sort(B.begin(),B.end(),comparator);
for(int i = 0;i < B.size();i++){
cout<<B[i].I<<" "<<B[i].V<<endl;
}
}
But I got runtime error. Please help.
Upvotes: 2
Views: 645
Reputation: 114579
Normally what is done is the opposite... i.e. given an array x
of elements compute an array of integers ix
so that x[ix[i]]
appears to be sorted under a certain criteria.
This allows representing the container with different orderings without actually having to move/copy the elements.
With C++11 this can easily be done using lambdas:
// Build the index vector ix
std::vector<int> ix(x.size());
for (int i=0,n=x.size(); i<n; i++) ix[i] = i;
// Sort ix according to the corresponding values in x
// (without touching x)
std::sort(ix.begin(), ix.end(),
[&x](int a, int b) { return x[a] < x[b]; });
This ix
index array is what you are asking for (i.e. the "old" position of an element: ix[i]
is where the i
-th element of the sorted list was in the original array) and there is no need to modify the input array.
Upvotes: 1
Reputation: 7867
do you pefer to use vector and pair?
each pair has "first" and "second", put "first"=value to sort,"second"=original index, create a pair for each element and put them into vector to sort:
int N[]={10,11,3,15,8,7};
std::vector<std::pair<int,int> > v;
//create pair for each element
for(int i=0;i<sizeof(N)/sizeof(int);i++){
//first is value of array,second is original index
v.push_back(std::make_pair(N[i],i));
}
//sort the vector of pair
sort(v.begin(),v.end());
//get original index from second of pair
for(std::pair<int,int>& p : v){
std::cout << p.first << ":" << p.second << std::endl;
}
output
3:2
7:5
8:4
10:0
11:1
15:3
Upvotes: 2
Reputation: 361762
This code is wrong:
vector<VnI> B;
for(int i = 0;i < A.size();i++){
B[i].I = i;
B[i].V = A[i];
}
When you write B[i]
, it assumes that B
is at least of size i+1
. Since the maximum value of i
(which you used an index to B
) is A.size()-1
. The assumption in your code is that B
is at least of size A.size()
. This assumption is wrong — the fact is that B
is of size 0
.
Unfortunately operator[]
of std::vector
doesn't check for out of range index. If you use at()
, the code will throw std::out_of_range
exception:
vector<VnI> B;
for(int i = 0;i < A.size();i++){
B.at(i).I = i;
B.at(i).V = A[i];
}
Now this would throw std::out_of_range
exception.
Anyway, one simple fix could be this:
vector<VnI> B (A.size()); //initialize B with the size of A.
for(int i = 0;i < A.size();i++){
B[i].I = i;
B[i].V = A[i];
}
However, I'd suggest this solution:
vector<VnI> B;
B.reserve(A.size());
for(int i = 0;i < A.size(); i++){
B.emplace_back(i, A[i]);
}
I'd also suggest you read more about std::vector
, especially the following functions:
size()
capacity()
resize()
reserve()
push_back()
operator[]
at()
emplace_back()
Also, learn to naming your variables properly and be consistent with it.
Hope that helps.
Upvotes: 2
Reputation: 470
You are trying to sort a list of custom objects, answerd here:
Once you list the list
of VnI
objects you can then access there old index's through the I
member that I presume is the index.
Upvotes: -1