Optimizing calculating combination and avoiding overflows

前端 未结 2 1294
借酒劲吻你
借酒劲吻你 2021-01-25 01:42

I am solving a programming problem which is stuck at calculating nCr efficiently and at the same time avoiding overflows. I have made the following trivial simplifi

相关标签:
2条回答
  • 2021-01-25 02:21

    I had to solve this problem, too. What I did was use the fact that there are the same number of multiplications as divisions and bundled them together, taking one multiplication and one division at a time. It comes out as an integer at the end, but I use double for the intermediate terms and then round to the nearest integer at the end.

    // Return the number of combinations of 'n choose k'
    unsigned int binomial(unsigned int n, unsigned int k) {
    unsigned int higher_idx;
    unsigned int lower_idx;
    if(k > n-k) {
        higher_idx = k;
        lower_idx = n - k;
    } else {
        higher_idx = n - k;
        lower_idx = k;
    }
    double product = 1.0;
    double factor;
    unsigned int idx;
    for(idx=n; idx>higher_idx; idx--) {
        factor = (double)idx / double(lower_idx - (n - idx));
        product *= factor;
    }
    return (unsigned int)(product + 0.5);
    }
    
    0 讨论(0)
  • 2021-01-25 02:31

    I found an interesting solution here: http://blog.plover.com/math/choose.html

        unsigned choose(unsigned n, unsigned k) {
          unsigned r = 1;
          unsigned d;
          if (k > n) return 0;
          for (d=1; d <= k; d++) {
            r *= n--;
            r /= d;
          }
          return r;
        }
    

    This avoids overflows (or at least limits the problem) by performing multiplication and division alternatively.

    E.g. for n = 8, k = 4:

    result = 1;
    result *= 8;
    result /= 1;
    result *= 7;
    result /= 2;
    result *= 6;
    result /= 3;
    result *= 5;
    result /= 4;
    done
    
    0 讨论(0)
提交回复
热议问题