优化的阵列移位方法

时间:2013-06-07 10:43:09

标签: objective-c sorting nsmutablearray

我有NSMutableArray持有NSStrings,例如{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

我希望能够用包装来移动元素。

所以,例如移动1到中心,移动所有元素,将剩余的元素(越过边界)包裹起来再次开始,反之亦然,例如10到中心。

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

是否存在已经存在的优化sort方法?

5 个答案:

答案 0 :(得分:2)

我不知道NSArray上的任何方法,但是:

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];
}

e.g:

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

应该按照你的描述做。

登录控制台:

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

可能没有表现力。

答案 1 :(得分:2)

最有效的方法是创建一个包装器对象,该对象维护数组的当前“原点”,并通过添加该模型长度来重新解释索引。事实上,如果只在少数几个地方访问数组,这很容易用1-2行内联代码完成。

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

(如果这扩展了NS(Mutable)数组,那么“array”就是“超级”。如果只有一个包装器,那么“array”是一个实例var。“origin”在任何一种情况下都是一个实例var / property。)

答案 2 :(得分: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]);
}

答案 3 :(得分:0)

当然,如果您要移动N元素,那么必须包围所有你要做的就是取最后的N数组元素并将它们粘在前面?

如果你换另一种方式,就把前面放在后面。

答案 4 :(得分:0)

旋转基本上是通过从数组的一端获取N个元素并将它们放在另一端来完成的。如果需要,可以使用不可变数组执行此操作,但可变数组提供稍微清晰的实现。

对于向左旋转,最简单的方法可能就是:

// 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

向右旋转将类似,但范围将位于数组的末尾,并且您将使用-insertObjects:atIndexes:插入从索引0开始的对象:

// 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