2013-06-07 34 views
5

Tôi có một số NSMutableArray giữ NSStrings ví dụ: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}Phương pháp thay đổi mảng tối ưu

Tôi muốn có thể thay đổi các phần tử bằng gói.

Vì vậy, ví dụ: di chuyển 1 đến trung tâm, dịch chuyển tất cả các phần tử, bao quanh các phần tử còn lại (vượt qua giới hạn) để bắt đầu lại và ngược lại, ví dụ: 10 đến trung tâm.

{7, 8, 9, 10, 1, 2, 3, 4, 5, 6}{6, 7, 8, 9, 10, 1, 2, 3, 4, 5}

Có một tối ưu hóa sort phương pháp như thế này đã tồn tại?

+1

tôi nghĩ rằng chúng ta có thể làm điều đó trong thời gian tuyến tính với một 'vòng for', một cho người đầu tiên' k' yếu tố nói 1-6 và tiếp theo cho còn 'yếu tố m' tức 7-10. và 'k + m = n' là kích thước của mảng. Nhưng tôi không biết về bất kỳ thuật toán chuẩn nào như vậy. –

+0

@PraveenS - 'trueIndex = (offset + index)% array.count'. Tôi nghĩ rằng đó là tốt hơn so với thời gian tuyến tính. –

Trả lời

2

Cách tiếp cận hiệu quả nhất là tạo đối tượng bao bọc duy trì "nguồn gốc" hiện tại của mảng và diễn giải lại chỉ mục bằng cách thêm nguồn gốc đó, điều chỉnh độ dài. Trong thực tế, nếu mảng chỉ được truy cập trong một số ít các địa điểm, điều này có thể dễ dàng thực hiện với 1-2 dòng mã trong dòng.

-(id)objectForIndex:(NSInteger) index { 
    NSInteger realIndex = (origin + index) % array.count; 
    return [array objectAtIndex:realIndex]; 
} 

(Nếu đây kéo dài NS (Mutable) Mảng sau đó "mảng" là "siêu". Nếu chỉ có một wrapper sau đó "mảng" là một var ví dụ. "Nguồn gốc" là một ví dụ var/bất động sản trong cả hai trường hợp .)

+0

Thông minh, không cần phải thay đổi. – jarryd

+0

Modulo! Thiên tài! –

0

chắc chắn nếu bạn đang di chuyển bởi N các yếu tố phải bao quanh tất cả những gì bạn cần làm là lấy các phần tử mảng N cuối cùng và dán chúng ở phía trước?

và nếu bạn đang di chuyển theo cách khác, hãy đặt mặt trước và đặt ở mặt sau.

2

Tôi không biết về bất kỳ phương pháp trên NSArray cho điều này, nhưng:

static NSArray *shiftArray(NSArray *array, NSInteger pos) 
{ 
    NSInteger length = [array count]; 
    NSArray *post = [array subarrayWithRange:(NSRange){ .location = length - pos, .length = pos }]; 
    NSArray *pre = [array subarrayWithRange:(NSRange){ .location = 0, .length = length - pos}]; 
    return [post arrayByAddingObjectsFromArray:pre]; 
} 

ví dụ .:

NSArray *array = @[@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I"]; 
NSLog(@"array = %@",shiftArray(array, 4)); 

nên làm những gì bạn mô tả.

Logs ra cửa sổ Console:

array = (
    F, 
    G, 
    H, 
    I, 
    A, 
    B, 
    C, 
    D, 
    E 
) 

có khả năng không performant.

0

Xoay về cơ bản được thực hiện bằng cách lấy phần tử N từ một đầu của mảng và đặt chúng ở đầu kia thay thế. Bạn có thể làm điều này với các mảng bất biến nếu bạn muốn, nhưng các mảng có thể thay đổi được cung cấp một cách thực hiện hơi sạch hơn.

Đối xoay trái, cách đơn giản nhất là có lẽ chỉ:

// Make sure we don't overrun the array if the rotation is larger. 
numberOfObjectsToRotateLeft %= array.count; 

NSRange range = NSMakeRange(0, numberOfObjectsToRotateLeft); 
NSMutableArray * rotatedArray = [array mutableCopy]; 

[rotatedArray addObjectsFromArray:[rotatedArray subarrayWithRange:range]]; 
[rotatedArray removeObjectsInRange:range]; 

// now return or use rotatedArray 

Xoay đúng sẽ là tương tự, nhưng phạm vi sẽ là vào cuối mảng, và bạn muốn chèn các đối tượng bắt đầu từ chỉ số 0 với -insertObjects:atIndexes::

// Make sure we don't overrun the array if the rotation is larger. 
numberOfObjectsToRotateRight %= array.count; 

NSRange range = NSMakeRange(array.count - numberOfObjectsToRotateRight, numberOfObjectsToRotateRight); 
NSMutableArray * rotatedArray = [array mutableCopy]; 

NSArray * movedObjects = [rotatedArray subarrayWithRange:range]; 
[rotatedArray removeObjectsInRange:range]; 
[rotatedArray insertObjects:movedObjects atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, numberOfObjectsToRotateRight)]]; 

// now return or use rotatedArray 
1
-(NSArray*)shiftForward:(BOOL)forward withbits:(int)bit 
{ 
    NSInteger length = [array count]; 
    NSArray *right; 
    NSArray *left; 

    if (forward) { 
     //code for right shift 
     right = [array subarrayWithRange:(NSRange){ .location = length - bit, .length = bit }]; 
     left = [array subarrayWithRange:(NSRange){ .location = 0, .length = length - bit}]; 
     return [right arrayByAddingObjectsFromArray:left]; 
    }else{ 
     //code for left shift 
     left = [array subarrayWithRange:(NSRange){ .location =0, .length = bit }]; 
     right= [array subarrayWithRange:(NSRange){ .location = bit, .length = length - bit}]; 
     return [right arrayByAddingObjectsFromArray:left]; 
    } 
} 

- (void)viewDidLoad 
{ 
    array = @[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9"]; 
    NSLog(@"array is %@",[self shiftForward:YES withbits:3]); 
}