将递归JS函数转换为Obj-C

时间:2017-09-10 02:47:44

标签: javascript objective-c recursion objective-c-blocks

我的一位朋友帮我解决了计算问题,我试图根据某些条件创建一个系列。他使用JS进行递归。我坐下来把它翻译成Obj-C而且很难过。

我的起点如下。想法是使用递归块,这是正确的方法吗?块和递归对我来说真的很难理解。下面的骨架是在正确的轨道上吗?

JS版

function series(F, S, Y, N = 0, result = []) {
  var entry

  if (N < 2) {
    entry = N * (F + S * (N - 1))
  } else {
    entry = (F + S * (N - 1))
  }

  if (entry > Y) {
    return result
  }

  result.push(entry)

  return series(F, S, Y, N + 1, result)
}

// series (90, 30, 200)
// (5) [0, 90, 120, 150, 180]

开始尝试Obj-C版本 - 抱歉这很难看

-(NSArray*) seriesWithF:(int)_F S:(int)_S Y:(int)_Y {

int F = _F;
int S = _S;
int Y = _Y;
int N = 0;
NSMutableArray* result = [NSMutableArray init];

    __block void ( ^series)(int, int, int, int, NSMutableArray*) = ^ void (int F, int S, int Y, int N, NSMutableArray* result) 
    {

    // logic
    int entry = [result of logic]
    [result addObject:[NSNumber initWithInt:entry]];

     series(F, S, Y, N, result);

    }

 series(F, S, Y, N, result);
 return result;

}     

2 个答案:

答案 0 :(得分:1)

不需要块。一个更直接的翻译工作:

- (NSArray *)series:(int)f s:(int)s y:(int)y n:(int)n result:(NSArray *)result {
    int entry;
    if (n < 2) {
        entry = n * (f + s * (n - 1));
    } else {
        entry = (f + s * (n - 1));
    }

    if (entry > y) {
        return result;
    }

    NSMutableArray *newResult = [result mutableCopy];
    [newResult addObject:@(entry)];

    return [self series:f s:s y:y n:n+1 result:newResult];
}

- (void)someOtherMethod {
    NSArray *result = [self series:90 s:30 y:200 n:0 result:@[]];
    NSLog(@"Result = %@", result);
}

答案 1 :(得分:1)

看起来您使用了一个块来解决缺少默认参数值(对于Nresult),您的代码大纲本身没有任何问题但更简单的方法是使用本地(static)C函数来完成工作。为此,只需将JS转换为等效的C,然后使用Objective-C方法调用此C函数,传入Nresult的值。

然而,在这种特殊情况下,你的朋友解决方案比它需要的更复杂,一个更简单的算法将产生你的系列。

考虑第一个条件N < 2,其中N从零开始,仅对0&amp; 1。在第一种情况下,entry将设置为0,而第二种情况将设置为与else分支中相同的值...一种设置第一个值的复杂方法你的序列为零。

接下来考虑递归;调用中没有任何复杂的内容,只有一个参数递增。通过迭代可以轻松地增加值。

最后,每个递归调用都会“从头开始”计算下一个值,但下一个值只是添加了S的前一个值。迭代再适用于此。

基于这些观察,我们简化:

- (NSArray *) seriesWithF:(int)F S:(int)S Y:(int)Y
{
   NSMutableArray *result = [NSMutableArray new];
   [result addObject:@(0)];        // you always start with zero

   int entry = F;                  // next value is F
   while (entry <= Y)              // iterate as long as in range
   {
      [result addObject:@(entry)]; // add to sequence
      entry += S;                  // increment
   }

   return result;
}

HTH