将递归 JS 函数翻译成 Obj-C
Translate recursive JS function into Obj-C
我的一个朋友帮助我解决了一个计算问题,我试图根据某些条件创建一个系列。他使用 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;
}
不需要块。更直接的翻译作品:
- (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);
}
看起来您已经使用块来解决缺少默认参数值的问题(对于 N
和 result
),您的代码大纲没有任何问题 per se 但更简单的方法是使用本地 (static
) C 函数来完成这项工作。为此,只需将 JS 转换为等效的 C,然后使用您的 Objective-C 方法调用此 C 函数,传入 N
和 result
.
的值
但是在这种特殊情况下,您朋友的解决方案比需要的更复杂,一个更简单的算法将产生您的系列。
考虑第一个条件 N < 2
,给定 N
从零开始,仅对 0
和 1
为真。在第一种情况下 entry
将被设置为 0
并且在第二种情况下将设置为与 else
分支中相同的值...设置第一个值的复杂方法你的序列归零。
接下来考虑递归;调用中没有什么复杂的东西,只是增加了一个参数。通过迭代很容易增加一个值。
最后每个递归调用计算下一个值 "from scratch",但下一个值只是前一个值加上 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
我的一个朋友帮助我解决了一个计算问题,我试图根据某些条件创建一个系列。他使用 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;
}
不需要块。更直接的翻译作品:
- (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);
}
看起来您已经使用块来解决缺少默认参数值的问题(对于 N
和 result
),您的代码大纲没有任何问题 per se 但更简单的方法是使用本地 (static
) C 函数来完成这项工作。为此,只需将 JS 转换为等效的 C,然后使用您的 Objective-C 方法调用此 C 函数,传入 N
和 result
.
但是在这种特殊情况下,您朋友的解决方案比需要的更复杂,一个更简单的算法将产生您的系列。
考虑第一个条件 N < 2
,给定 N
从零开始,仅对 0
和 1
为真。在第一种情况下 entry
将被设置为 0
并且在第二种情况下将设置为与 else
分支中相同的值...设置第一个值的复杂方法你的序列归零。
接下来考虑递归;调用中没有什么复杂的东西,只是增加了一个参数。通过迭代很容易增加一个值。
最后每个递归调用计算下一个值 "from scratch",但下一个值只是前一个值加上 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