Пример #1
0
        BinCoeffBase BCB; // Holds ref to actual binomial coeff class - Bincoeff (uint), BinCoeffL (ulong), or BinCoeffBigInt (BigInteger).
        //
        public BinCoeffGen(int numItems, int groupSize, bool initTable = false)
        {
            // This constructor builds the index tables used to retrieve the index to the binomial coefficient table.
            // n is the number of items and k is the number of items in a group, and reflects the case n choose k.
            //
            // Get the total number of unique combinations.
            BigInteger totalCombos = BinCoeffBase.GetCombosCountBigInt(numItems, groupSize);

            // If n & k result in overflow of ulong, then use BigInteger. Otherwise either use int or long for best performance.
            if (totalCombos > ulong.MaxValue)
            {
                BCB = new BinCoeffBigInt(numItems, groupSize, totalCombos);
            }
            else if (totalCombos <= int.MaxValue)
            {
                BCB = new BinCoeff <T>(numItems, groupSize, (uint)totalCombos, initTable);
            }
            else
            {
                BCB = new BinCoeffL(numItems, groupSize, (ulong)totalCombos);
            }
        }
Пример #2
0
        public static void OutputCombos <U>(string filePath, string[] dispChars, string sep, string groupSep, int maxCharsInLine,
                                            BinCoeffBase bcb, U startRank, U endRank)
        {
            // This function writes out the K indexes in sorted order to either a file or a list. It is used by all 3 implementations.
            // U specifies uint, ulong, or BigInteger.
            // filePath - path & name of file.
            // dispChars - if not null, then the string in DispChars is displayed instead of the
            //    numeric value of the corresponding combination.
            // sep - String used to separate each individual combination in a group.
            // groupSep - String used to separate each combination group.
            // maxCharsInLine - maximum number of chars in an output line.
            // bcb - the type to be worked on - either Bincoeff (uint), BincoeffL (ulong), or BinCoeffBig (BigInteger).
            // startRank - the first combo that should be output. Range is zero to NumCombos - 1.
            // endRank - the last combo that should be output. If startRank > endRank, then output is in descending order.
            //
            // No more than 2^31 combinations are output.
            //
            const int     bufferSize = 65536;
            int           loop1, n, outPos = 0;
            int           offset = 0, inc, outCount = 0, elemCount = 0;
            int           maxCharsInN = bcb.NumItems / 10 + 1;
            var           kIndexes = new int[bcb.GroupSize];
            var           outbuf = new byte[maxCharsInLine + 2];
            string        s, s1;
            StringBuilder sb      = new StringBuilder();
            FileStream    outFile = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, FileOptions.None);
            // Set to output in ascending or descending order depending if startRank < endRank.
            dynamic dynStart = startRank, dynEnd = endRank;

            inc      = (dynStart > dynEnd) ? -1 : 1;
            outCount = (dynEnd - dynStart) * inc;
            // Output the K Indexes
            do
            {
                bcb.GetCombFromRank(startRank, offset, kIndexes);
                offset += inc;
                for (loop1 = 0; loop1 < bcb.GroupSize; loop1++)
                {
                    n = kIndexes[loop1];
                    if (dispChars != null)
                    {
                        s = dispChars[n];
                    }
                    else
                    {
                        s1 = "{0, " + maxCharsInN.ToString() + "}";
                        s  = String.Format(s1, kIndexes[loop1]);
                    }
                    sb.Append(s);
                    if (loop1 < bcb.GroupSizeM1)
                    {
                        sb.Append(sep);
                    }
                }
                if (outPos + sb.Length >= maxCharsInLine)
                {
                    outbuf[outPos++ - groupSep.Length] = (byte)'\r';
                    outbuf[outPos - groupSep.Length]   = (byte)'\n';
                    outFile.Write(outbuf, 0, outPos - groupSep.Length);
                    outPos = 0;
                }
                sb.Append(groupSep);
                // Move the string value to the output buffer.
                for (loop1 = 0; loop1 < sb.Length; loop1++)
                {
                    outbuf[outPos++] = (byte)sb[loop1];
                }
                sb.Remove(0, sb.Length);
                elemCount++;
            } while (elemCount <= outCount);
            if (outPos > 0)
            {
                outFile.Write(outbuf, 0, outPos - groupSep.Length);
            }
            outFile.Close();
            outFile.Dispose();
        }