Reputation: 45
Here is a example of what I want to do with NSArray contains NSNumber.
This is the NSArray "score" I want to edit.
score[0]=30,
score[1]=10,
score[2]=20
score[3]=0
Sort the Array in ascending-order
score[0]=30 //[0]This number shows the index before sorting the array
score[1]=20 //[2]
score[2]=10 //[1]
score[3]=0 //[3]
Edit the Array(In this case,4th gives 1st 10 points,and 3rd gives 2nd 5points)
score[0]=40 //[0]
score[1]=25 //[2]
score[2]=5 //[1]
score[3]=-10 //[3]
And sort the array back they were.
score[0]=40
score[1]=5
score[2]=25
score[3]=-10
I have a problem with no.4 method in the list.Can someone give me some idea with this?
Thanks in advance.
Upvotes: 1
Views: 211
Reputation: 53010
[Code will be typed in, check it!]
I assume your score
array is actually mutable as you intend to alter it:
NSMutableArray *score = ...;
Create another array the same size and initialized to 0..n:
NSMutableArray *indices = [NSMutableArray arrayWithCapacity:[score count]];
// add the numbers 0..[score count] to indices
Now sort the indices
array using a custom comparator which looks up the score
array:
[indices sortUsingComparator:(NSComparator)^(NSNumber *a, NSNumber *b)
{
return [((NSNumber *)[[score objectAtIndex:[a integerValue]])
compare:[[score objectAtIndex:[b integerValue]]
];
}
]
Now you can modify your original array via the indices array, e.g. to modify the "4th" element after the source:
[score replaceObjectAtIndex:[[indices objectAtIndex:3] integerValue] withObject:...];
Now you don't need to "unsort" score
at all, your step 4 is "do nothing".
Upvotes: 0
Reputation: 882206
You don't actually need to swap the values themselves, you can set up an extra level of indirection and use that.
Before the sort, you have the indexes initialised to point to the corresponding scores:
index[0] = 0 score[0] = 30
index[1] = 1 score[1] = 10
index[2] = 2 score[2] = 20
index[3] = 3 score[3] = 0
When you sort, you actually sort the indexes based on the scores they point to rather than the scores themselves. So, instead of the following comparison in your sort:
if score[i] > score[i+1] then swap score[i], score[i+1]
you instead use:
if score[index[i]] > score[index[i+1]] then swap index[i], index[i+1]
Following the sort, you then have:
index[0] = 0 score[0] = 30
index[1] = 2 score[1] = 10 \ These two indexes have been swapped
index[2] = 1 score[2] = 20 / but NOT the scores.
index[3] = 3 score[3] = 0
Then, to move points, you use the indirect indexes rather than the direct values:
score[index[0]] += 10; score[index[3]] -= 10;
score[index[1]] += 5; score[index[2]] -= 5;
Then you throw away the indexes altogether, the original array doesn't need restoration to its original order, simply because its order was never changed.
Upvotes: 3
Reputation: 9597
Make an additional array initialized as such:
index[0] = 0
index[1] = 1
index[2] = 2
:
And every time your sorting algorithm swaps two indices in score
, you also swap the same indices in index
.
In case your sorting algorithm is built-in, so that you have no control over it, you will have to replace each score with a tuple (an object, a two-element array, whichever is easier in objective-c), where on element is the score, and the other element is its original index. When you sort, you would pass a custom comparator to the sorting function, so that only the score is used for comparison. That would sort your score-index tuples, so that you can use the index to restore them to original order.
Upvotes: 0