pongeponge.hatenablog.jp
前回、説明にもならない説明をポチポチ書いてて「elementsいらんくない?」と思ったので省いた。
using System.Numerics; public partial class MathPlus { public class Combination { /// <summary> /// 要素の個数 /// </summary> private int _n; /// <summary> /// 選択する個数 /// </summary> private int _k; private int[] _pattern; /// <summary> /// 組み合わせの数 /// </summary> public BigInteger Count { get { return this.Combination_Count(); } } /// <summary> /// コンストラクタ /// </summary> /// <param name="n">要素の個数</param> /// <param name="k">選択する個数</param> public Combination(int n, int k) { this._n = n; this._k = k; this._pattern = Enumerable.Range(1, this._k).ToArray(); } /// <summary> /// 組み合わせの数を求める /// </summary> /// <returns>組み合わせの数</returns> private BigInteger Combination_Count() { var numerator = new BigInteger(1); var denominator = new BigInteger(1); var n = this._n; var k = this._k; var tmp = 1L; if (this._k > this._n - this._k) k = this._n - this._k; for (int count = 1; count <= k; count++) { numerator *= n; n--; denominator *= tmp; tmp++; } return numerator / denominator; } /// <summary> /// 組み合わせパターンを得る /// </summary> /// <returns>組み合わせパターンの反復子</returns> public IEnumerable<int[]> GetEnumerable() { if (this._pattern.Length == 0) yield break; while (this._pattern[this._pattern.Length - 1] != this._n + 1) { yield return this._pattern; Update(); } yield break; } /// <summary> /// 参照の更新 /// </summary> private void Update() { for (int i = this._pattern.Length - 1; i >= 0; i--) { if (this._pattern[i] != this._n + 1) { this._pattern[i]++; for (int r = i + 1; r < this._pattern.Length; r++) { this._pattern[r] = this._pattern[r - 1] + 1; } } if (this._pattern[this._pattern.Length - 1] != this._n + 1) break; } } } }
やっぱりelementsいらんかったわ。