C#:不重复的骰子排列

C#:不重复的骰子排列,c#,math,permutation,combinatorics,C#,Math,Permutation,Combinatorics,如何更改下面的C#代码以列出所有可能的排列而不重复?例如:两个掷骰子的结果将产生1,1,2,这意味着2,1,1不应该出现 下面是我的代码: string[] Permutate(int input) { string[] dice; int numberOfDice = input; const int diceFace = 6; dice = new string[(int)Math.Pow(diceFace, numberOfD

如何更改下面的C#代码以列出所有可能的排列而不重复?例如:两个掷骰子的结果将产生1,1,2,这意味着2,1,1不应该出现

下面是我的代码:

string[] Permutate(int input)
{
        string[] dice;
        int numberOfDice = input;
        const int diceFace = 6;
        dice = new string[(int)Math.Pow(diceFace, numberOfDice)];
        int indexNumber = (int)Math.Pow(diceFace, numberOfDice);
        int range = (int)Math.Pow(diceFace, numberOfDice) / 6;

        int diceNumber = 1;
        int counter = 0;

        for (int i = 1; i <= indexNumber; i++)
        {
            if (range != 0)
            {
                dice[i - 1] += diceNumber + " ";
                counter++;
                if (counter == range)
                {
                    counter = 0;
                    diceNumber++;
                }
                if (i == indexNumber)
                {
                    range /= 6;
                    i = 0;
                }
                if (diceNumber == 7)
                {
                    diceNumber = 1;
                }
            }
            Thread.Sleep(1);
        }
        return dice;
    }
string[]置换(int输入)
{
字符串[]骰子;
int numberOfDice=输入;
const int diceFace=6;
dice=新字符串[(int)Math.Pow(diceFace,numberOfDice)];
int indexNumber=(int)Math.Pow(diceFace,numberOfDice);
int range=(int)Math.Pow(diceFace,numberOfDice)/6;
整数=1;
int计数器=0;

对于(inti=1;i我的数学也不好,这可能有帮助,也可能没有帮助

Program.cs

namespace Permutation
{
    using System;
    using System.Collections.Generic;

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Generating list.");

            var dice = new List<ThreeDice>();

            for (int x = 1; x <= 6; x++)
            {
                for (int y = 1; y <= 6; y++)
                {
                    for (int z = 1; z <= 6; z++)
                    {
                        var die = new ThreeDice(x, y, z);

                        if (dice.Contains(die))
                        {
                            Console.WriteLine(die + " already exists.");
                        }
                        else
                        {
                            dice.Add(die);
                        }
                    }
                }
            }

            Console.WriteLine(dice.Count + " permutations generated.");

            foreach (var die in dice)
            {
                Console.WriteLine(die);
            }

            Console.ReadKey();
        }
    }
}
名称空间置换
{
使用制度;
使用System.Collections.Generic;
班级计划
{
静态void Main(字符串[]参数)
{
Console.WriteLine(“生成列表”);
var dice=新列表();

对于(intx=1;x我能想到的最简单的方法:

List<string> dices = new List<string>();
for (int i = 1; i <= 6; i++)
{
    for (int j = i; j <= 6; j++)
    {
        for (int k = j; k <= 6; k++)
        {
            dices.Add(string.Format("{0} {1} {2}", i, j, k));
        }
    }
}
列表骰子=新列表();

对于(int i=1;i问题的重要部分是您需要不同的集合(无论顺序如何)。例如,[1,2,1]的骰子卷等于[1,1,2]的骰子卷

我相信有很多种方法可以剥这只猫的皮,但首先想到的是创建一个EqualityComparer,它将以您想要的方式比较骰子列表,然后使用LINQ和
Distinct()
方法

下面是
相等比较程序
,它采用2个
列表
,表示如果元素都相等(无论顺序如何),则它们相等:


希望对您有所帮助!

我编写了一个类来处理处理处理二项式系数的常见函数,这是您的问题所属的问题类型。它执行以下任务:

  • 将任意N选择K的所有K索引以良好格式输出到文件中。K索引可以用更多描述性字符串或字母替换。此方法使解决此类问题变得非常简单

  • 将K-索引转换为排序二项系数表中某项的适当索引。此技术比依赖迭代的较旧已发布技术快得多。它通过使用Pascal三角形固有的数学特性来实现。我的论文讨论了这一点。我相信我是第一个发现并发布这是技术,但我可能错了

  • 将已排序的二项式系数表中的索引转换为相应的K索引

  • 使用此方法计算二项式系数,它不太可能溢出,并且适用于较大的数字

  • 该类是用.NET C#编写的,提供了一种管理与问题相关的对象(如果有)的方法通过使用泛型列表。该类的构造函数接受一个名为InitTable的bool值,如果为true,将创建一个泛型列表来保存要管理的对象。如果该值为false,则它将不会创建该表。不需要创建该表来执行上述4种方法。访问器方法提供给acces这是桌子

  • 有一个相关的测试类,它展示了如何使用这个类及其方法。它已经用2个案例进行了广泛的测试,并且没有已知的bug

  • 要阅读这个类并下载代码,请参阅。

    这里是使用递归的通用c#版本(基本上,递归方法使用骰子数或掷骰子的次数),并返回所有组合字符串(例如,对于问题中的'3',将有56个这样的组合)

    public string[]getDice组合(int noofdice或nooftossesofdice)
    {
    noofdicessornooftossesofdice.Throw(“noofdicessornooftossofdice”,
    n=>n
    
    List<string> dices = new List<string>();
    for (int i = 1; i <= 6; i++)
    {
        for (int j = i; j <= 6; j++)
        {
            for (int k = j; k <= 6; k++)
            {
                dices.Add(string.Format("{0} {1} {2}", i, j, k));
            }
        }
    }
    
        private class ListComparer : EqualityComparer<List<int>>
        {
            public override bool Equals(List<int> x, List<int> y)
            {
                if (x.Count != y.Count)
                    return false;
                x.Sort();
                y.Sort();
                for (int i = 0; i < x.Count; i++)
                {
                    if (x[i] != y[i])
                        return false;
                }
                return true;
            }
            public override int GetHashCode(List<int> list)
            {
                int hc = 0;
                foreach (var i in list)
                    hc ^= i;
                return hc;
            }
        }
    
        public static void Main()
        {
            var values = new[] { 1,2,3,4,5,6 };
            var allCombos = from x in values
                            from y in values
                            from z in values
                            select new List<int>{ x, y, z };
            var distinctCombos = allCombos.Distinct(new ListComparer());
    
            Console.WriteLine("#All combos: {0}", allCombos.Count());
            Console.WriteLine("#Distinct combos: {0}", distinctCombos.Count());
            foreach (var combo in distinctCombos)
                Console.WriteLine("{0},{1},{2}", combo[0], combo[1], combo[2]);
        }
    
    public string[] GetDiceCombinations(int noOfDicesOrnoOfTossesOfDice)
            {
                noOfDicesOrnoOfTossesOfDice.Throw("noOfDicesOrnoOfTossesOfDice",
                    n => n <= 0);
                List<string> values = new List<string>();
                this.GetDiceCombinations_Recursive(noOfDicesOrnoOfTossesOfDice, 1, "",
                    values);
                return values.ToArray();
            }
            private void GetDiceCombinations_Recursive(int size, int index, string currentValue,
                List<string> values)
            {
                if (currentValue.Length == size)
                {
                    values.Add(currentValue);
                    return;
                }
                for (int i = index; i <= 6; i++)
                {
                    this.GetDiceCombinations_Recursive(size, i, currentValue + i, values);
                }
            }
    
    [TestMethod]
            public void Dice_Tests()
            {
                int[] cOut = new int[] { 6, 21, 56, 126 };
                for(int i = 1; i<=4; i++)
                {
                    var c = this.GetDiceCombinations(i);
                    Assert.AreEqual(cOut[i - 1], c.Length);
                }
            }