अद्यतन: मेरी पहली एक से एक बेहतर समाधान के लिए नीचे देखें।
तुलनात्मक ब्लॉक का उपयोग करके सॉर्टिंग के साथ प्रत्येक नंबर और इसकी अनुक्रमणिका के लिए NSDictionary wrappers का उपयोग करके एक समाधान यहां दिया गया है। यह शायद बहुत अच्छी तरह से स्केल नहीं करता है, लेकिन यह काम पूरा हो जाता है।
static NSString *const kValueKey = @"value";
static NSString *const kIndexKey = @"index";
+ (void)searchArray:(NSArray *)array forClosestValuesTo:(int)value resultValues:(NSArray **)values resultIndexes:(NSArray **)indexes
{
NSMutableArray *searchObjs = [NSMutableArray arrayWithCapacity:[array count]];
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[searchObjs addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, kValueKey, [NSNumber numberWithUnsignedInt:idx], kIndexKey, nil]];
}];
[searchObjs sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSUInteger d1 = ABS([[obj1 objectForKey:kValueKey] intValue] - value);
NSUInteger d2 = ABS([[obj2 objectForKey:kValueKey] intValue] - value);
if (d1 == d2) { return NSOrderedSame; }
if (d1 < d2) { return NSOrderedAscending; }
return NSOrderedDescending;
}];
NSArray *results = [searchObjs subarrayWithRange:NSMakeRange(0, 3)];
if (values) {
*values = [results valueForKey:kValueKey];
}
if (indexes) {
*indexes = [results valueForKey:kIndexKey];
}
}
अद्यतन: यहाँ एक अद्यतन समाधान है कि इंडेक्सों का एक सी सरणी सॉर्ट करता है, NSDictionary रैपर की आवश्यकता को समाप्त
static NSString *const kValueKey = @"value";
static NSString *const kArrayKey = @"array";
int
CSCompareIndexes(void *data, const void *value1, const void *value2)
{
NSDictionary *dict = (NSDictionary *)data;
NSArray *array = [dict objectForKey:kArrayKey];
int valueToFind = [[dict objectForKey:kValueKey] intValue];
int index1 = *(int *)value1;
int index2 = *(int *)value2;
NSNumber *num1 = [array objectAtIndex:index1];
NSNumber *num2 = [array objectAtIndex:index2];
return ABS([num1 intValue] - valueToFind) - ABS([num2 intValue] - valueToFind);
}
void
CSSearchNumberArray(NSArray *array, int valueToFind, NSArray **resultValues, NSArray **resultIndexes)
{
NSInteger numValues = [array count];
NSUInteger *indexes = malloc(sizeof(NSUInteger) * numValues);
assert(indexes);
int i;
for (i = 0; i < numValues; i++) {
indexes[i] = i;
}
NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:array, kArrayKey, [NSNumber numberWithInt:valueToFind], kValueKey, nil];
qsort_r(indexes, numValues, sizeof(NSUInteger), (void *)data, CSCompareIndexes);
NSMutableArray *tmpValues = [NSMutableArray arrayWithCapacity:3],
*tmpIndexes = [NSMutableArray arrayWithCapacity:3];
for (i = 0; i < 3; i++) {
[tmpValues addObject:[array objectAtIndex:indexes[i]]];
[tmpIndexes addObject:[NSNumber numberWithInt:indexes[i]]];
}
if (resultValues) {
*resultValues = [NSArray arrayWithArray:tmpValues];
}
if (resultIndexes) {
*resultIndexes = [NSArray arrayWithArray:tmpIndexes];
}
free(indexes);
}
int main (int argc, char *argv[])
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSMutableArray *test = [NSMutableArray array];
int i;
for (i = 0; i < 10; i++) {
[test addObject:[NSNumber numberWithInt:(arc4random() % 100)]];
}
NSLog(@"Searching: %@", test);
NSArray *values, *indexes;
CSSearchNumberArray(test, 50, &values, &indexes);
NSLog(@"Values: %@", values);
NSLog(@"Indexes: %@", indexes);
[pool drain];
return 0;
}
मुझे लगता है कि मी का सबसे आसान तरीका देखना होगा इनिमुन नंबर, इसे हटाएं, और मिनीमुन नंबर फिर से देखें, आदि – TommyG
मैंने एक लूप लिखकर शुरू किया जो प्रत्येक नंबर का परीक्षण करता है, लेकिन मुझे जल्दी से एहसास हुआ कि मैं मूल से ऑब्जेक्ट्स का सूचकांक प्राप्त नहीं कर पाऊंगा सरणी। यह पता लगाना कि मेरे वास्तविक कार्यक्रम के लिए सूचकांक बहुत महत्वपूर्ण है - जो मैंने यहां पोस्ट किया है वह एक साधारण उदाहरण है, इसलिए मैं सिद्धांत – REDMX
सीख सकता हूं, जो आपको मिलने वाली संख्या की मूल अनुक्रमणिका को ट्रैक करने के लिए बहुत आसान होना चाहिए, लेकिन आप इसे बिना कर सकते हैं सरणी को संशोधित करना मान लें कि आप मिनट पाते हैं, आप इसकी अनुक्रमणिका (तीनों में से अपना पहला नंबर) रखते हैं, फिर इसे हटाने के बजाय, आप इसे अधिकतम संख्या से बदल सकते हैं - इस तरह, आप अपना सरणी नहीं बदलते .... – TommyG