0

我正在努力向 DDMathParser 添加一个新函数 (nCr)。我尝试按照 DDMathParser 的作者的这些说明进行操作:

https://stackoverflow.com/a/15599814/2521277

我的问题:我无法设法将 DDExpressions 与带有变量的复杂表达式结合起来......

你能帮我添加函数 nCr ( http://en.wikipedia.org/wiki/Binomial_coefficient#Factorial_formula )

谢谢!

4

1 回答 1

0

DDMathParser 作者在这里。

所有函数的基本签名是这样的:

DDExpression* ^(NSArray *arguments, NSDictionary *variables, DDMathEvaluator *evaluator, NSError **error);

因此,您需要创建实现 nCr 算法的这些块之一。有几种方法可以做到:

  1. 您可以完全按照文章中所示实现该函数,计算阶乘,进行减法和除法。
  2. 您可以完全根据现有的阶乘、减法和除法函数来实现该函数。
  3. 你可以将两者结合起来。

就个人而言,我推荐最后一个,因为它省去了重新评估参数的麻烦,但也意味着您不必自己编写大部分逻辑。

它会是这样的:

DDMathFunction nCrFunction = ^(NSArray *args, NSDictionary *vars, DDMathEvaluator *eval, NSError **error) {
  if ([args count] != 2) {
    *error = [NSError errorWithDomain:DDMathParserErrorDomain code:DDErrorCodeInvalidNumberOfArguments userInfo:@{NSLocalizedDescriptionKey : @"nCr requires 2 arguments"}];
    return nil;
  }

  DDExpression *first = [args objectAtIndex:0];
  DDExpression *second = [args objectAtIndex:1];

  NSNumber *n = [first evaluateWithSubstitutions:vars evaluator:eval error:error];
  if (n == nil) { return nil; }

  NSNumber *k = [second evaluateWithSubstitutions:vars evaluator:eval error:error];
  if (k == nil) { return nil; }

  // some validation here to guarantee that 0 ≤ k ≤ n

  // now, re-box the numbers in expressions to pass off to other functions
  DDExpression *nExpression = [DDExpression numberExpressionWithNumber:n];
  DDExpression *kExpression = [DDExpression numberExpressionWithNumber:k];

  // build the algorithm
  DDExpression *f1 = [DDExpression functionExpressionWithFunction:DDOperatorFactorial arguments:@[kExpression] error:error]; // k!

  // the other half of the denominator
  DDExpression *subtract = [DDExpression functionExpressionWithFunction:DDOperatorMinus arguments:@[nExpression, kExpression] error:error]; // (n-k)
  DDExpression *f2 = [DDExpression functionExpressionWithFunction:DDOperatorFactorial arguments:@[subtract] error:error]; // (n-k)!

  // the full denominator
  DDExpression *denominator = [DDExpression functionExpressionWithFunction:DDOperatorMultiply arguments:@[f1, f2] error:error]; // k!(n-k)!

  // the numerator
  DDExpression *numerator = [DDExpression functionExpressionWithFunction:DDOperatorFactorial arguments:@[nExpression] error:error]; // n!

  // the whole thing
  DDExpression *final = [DDExpression functionExpressionWithFunction:DDOperatorDivide arguments:@[numerator, denominator] error:error]; // n!/(k!(n-k)!)

  return final;
};

使用此块,您可以在您的DDMathEvaluator

[[DDMathEvaluator sharedMathEvaluator] registerFunction:nCrFunction forName:@"nCr"];

而已!

现在你可以这样做:

NSNumber *n = [@"nCr(4, 3)" numberByEvaluatingString];

警告:在浏览器中键入但未编译的代码。 警告实施者


顺便说一句,如果这是您希望看到 DDMathParser 内置的功能,请在 Github 上打开一个新问题。

于 2013-06-26T16:50:01.960 回答