5

我有一个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方法?

4

5 回答 5

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

例如:

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
)

可能没有性能。

于 2013-06-07T11:17:08.993 回答
2

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

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

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

于 2013-06-07T11:24:38.870 回答
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]);
}
于 2013-06-07T11:45:42.933 回答
0

当然,如果你要移动N必须环绕的元素,你会做的就是把最后一个N数组元素放在前面吗?

如果您要换另一种方式,则取前面并放在后面。

于 2013-06-07T11:16:25.683 回答
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

向右旋转类似,但范围将位于数组的末尾,并且您将从索引 0 开始插入对象-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
于 2013-06-07T11:34:37.843 回答