小心地从"循环"向量中删除N个项目(或者只是一个NSMutableArray)

Fat*_*tie 3 c++ iphone algorithm std

想象一下std:vector,比如说,当前有100个东西(0到99).你将它视为一个循环.所以第105项是索引4; 指数98的前锋7是5.

您想删除索引位置P后的N个项目.

所以,删除索引50后的5个项目; 简单.

或者在索引99之后有5个项目:当您删除0五次或4到0时,注意到99处的位置将被删除.

最糟糕的是,索引97之后的5个项目 - 你必须处理这两种删除模式.

什么是优雅和坚实的方法?

这是我写的一个无聊的例程

-(void)knotRemovalHelper:(NSMutableArray*)original
         after:(NSInteger)nn howManyToDelete:(NSInteger)desired
    {

#define ORCO ((NSInteger)[original count])

    static NSInteger kount, howManyUntilLoop, howManyExtraAferLoop;

    if ( ... our array is NOT a loop ... )
            // trivial, if messy...
        {
        for ( kount = 1; kount<=desired; ++kount  )
            {
            if ( (nn+1) >= ORCO )
                return;
            [original removeObjectAtIndex:( nn+1 )];
            }

        return;
        }
    else    // our array is a loop
            // messy, confusing and inelegant. how to improve?
            // here we go...
        {
        howManyUntilLoop = (ORCO-1) - nn;

        if ( howManyUntilLoop > desired )
            {
            for ( kount = 1; kount<=desired; ++kount  )
                [original removeObjectAtIndex:( nn+1 )];
            return;
            }

        howManyExtraAferLoop = desired - howManyUntilLoop;

        for ( kount = 1; kount<=howManyUntilLoop; ++kount  )
            [original removeObjectAtIndex:( nn+1 )];

        for ( kount = 1; kount<=howManyExtraAferLoop; ++kount )
            [original removeObjectAtIndex:0];

        return;
        }

#undef ORCO
    }
Run Code Online (Sandbox Code Playgroud)

更新!

InVariant的第二个答案导致了以下出色的解决方案."从"开始"比"开始"要好得多.所以例程现在使用"start with".Invariant的第二个答案导致了这个非常简单的解决方案......

如果P <currentsize删除P,则执行N次,否则删除0

-(void)removeLoopilyFrom:(NSMutableArray*)ra
    startingWithThisOne:(NSInteger)removeThisOneFirst
    howManyToDelete:(NSInteger)countToDelete
{
// exception if removeThisOneFirst > ra highestIndex
// exception if countToDelete is > ra size

// so easy thanks to Invariant:

for ( do this countToDelete times )
    {
    if ( removeThisOneFirst < [ra count] )
          [ra removeObjectAtIndex:removeThisOneFirst];
    else
          [ra removeObjectAtIndex:0];
    }
}
Run Code Online (Sandbox Code Playgroud)

更新!

Toolbox已经指出了一个新阵列工作的好主意 - 超级KISS.

Nic*_*ore 5

这是我头脑中的一个想法.

首先,生成一个表示要删除的索引的整数数组.所以"从索引97中删除5"将生成[97,98,99,0,1].这可以通过应用简单模数运算符来完成.

然后,对此数组进行降序排序,给出[99,98,97,1,0],然后按该顺序删除条目.

应该适用于所有情况.