繁体   English   中英

猜测可能组合的方法

[英]Method to guess possible combination

为了练习,我想编写一个程序来猜测x和y的随机位置。 例如,第一点是

int x = 0;
int y = 0;

x += rand.Next(0, 4);
y += rand.Next(0, 4);

然后从那个随机点开始,我将另一个随机值加到x和y上得到第二个点。 但是,我想返回以随机找到这些点。

提出要点:

int x = 0;
int y = 0;
List<Point> points = new List<Point>();

for (int i = 0; i < numberOfPointsWanted; i++)
{
    x += rand.Next(0, 4);
    y += rand.Next(0, 4);
    points.Add(new Point(x, y));
}

现在,我想猜测那些随机点,就好像我没有将它们存储在列表中一样。 因为每个新点都依赖于它的前任,所以我认为某种递归是必要的。 几乎就像蛮力猜测应用程序一样,可以找到那些要点。 我在完成该方法时遇到了麻烦,该方法能够在给定多个所需点的情况下猜测每个可能的点。

到目前为止,这是我找到的回合:

class Program
{
        static int nRounds = 2;
        static Point[] points = new Point[nRounds];
        static Point[] test = { new Point(1, 2), new Point(4, 1) };

        static bool CheckArray()
        {
            for (int i = 0; i < points.Length; i++)
                if (points[i] != test[i]) { return false; }

            return true;
        }

        static void PrintArray()
        {
            for (int i = 0; i < points.Length; i++)
                Console.Write("[" + tCount + "]\t" + points[i].X + " : " + points[i].Y + "\t");

            Console.Write("\n");
        }

        static int tCount = 0;
        static int rCount = 0;
        static void GetRounds(int inX, int inY)
        {
            for (int x = inX; x < 5; x++)
            {
                for (int y = inY; y < 5; y++)
                {
                    if (rCount < nRounds)
                    {
                        tCount++;
                        points[rCount] = new Point(x, y);
                        rCount++;
                        GetRounds(x, y);
                        if (CheckArray())
                        {
                            PrintArray();
                            return;
                        }
                        PrintArray();

                    }            
                }
            }
            rCount--;
        }

        static void Main(string[] args)
        {
            GetRounds(0, 0);
            Console.ReadKey();
        }
    }
}

我试图随机生成点,如上所示,然后根据代表所有这些点的哈希值猜测它们。

我期望看到的是:

如果只猜两点

Point one :: Point two x and y respectively

x y :: x y
0 0 :: 0 1
0 0 :: 0 2
0 0 :: 0 3
0 0 :: 1 0
0 0 :: 1 1
0 0 :: 1 2
0 0 :: 1 3
0 0 :: 2 0
0 0 :: 2 1
0 0 :: 2 2
0 0 :: 2 3
0 0 :: 3 0
0 0 :: 3 1
0 0 :: 3 2
0 0 :: 3 3
0 1 :: 0 0
0 1 :: 0 1
0 1 :: 0 2

依此类推,直到猜到了第一点和第二点的所有可能性

我不确定这是否正是您要寻找的东西,但是获取所有这些组合的一种方法是使用嵌套的for循环:

for (int ax = 0; ax < 4; ax++)
{
    for (int ay = 0; ay < 4; ay++)
    {
        var pointA = new Point(ax, ay);

        for (int bx = 0; bx < 4; bx++)
        {
            for (int by = 0; by < 4; by++)
            {                    
                var pointB = new Point(bx, by);

                Console.WriteLine($"{pointA.X} {pointA.Y} :: {pointB.X} {pointB.Y}");
            }
        }
    }
}

输出量

在此处输入图片说明


您在问一个解决方案,该方法允许传递可变数量的点。这非常简单-您只需保留结果的List<List<Point>> ,并在每次迭代时生成一个列表即可可能的点值(最小为0且最大为3时为16个可能的值),然后为新集中每个Point的现有结果中的每个项目生成一个新列表。

问题是结果集的大小。 由于如果我们的最小值为0且最大值为3,则单个点具有X和Y的16种可能组合,因此对于每个其他点,我们将16提升至该乘方。 因此,对于10点,组合超过十亿。

private static List<List<Point>> GetAllCombinations(int min, int max, int count)
{
    var results = new List<List<Point>>();

    for (int i = 0; i < count; i++)
    {
        var thisSet = new List<Point>();

        for (int x = min; x <= max; x++)
        {
            for (int y = min; y <= max; y++)
            {
                thisSet.Add(new Point(x, y));
            }
        }

        // If this is our first time through, we just add each point
        // as a single-item list to our results
        if (results.Count == 0)
        {
            foreach (var item in thisSet)
            {
                results.Add(new List<Point> {item});
            }
        }
        // On subsequent iterations, for each list in our results, and
        // for each item in this set, we create a new list for each item,
        // adding to it a copy of the existing result list. We clear
        // the results in the beginning (after making a copy) and then
        // add each new list to it in the inner loop.
        else
        {
            // Make a copy of our existing results and clear the original list
            var tempResults = results.ToList();
            results.Clear();

            foreach (var existingItem in tempResults)
            {
                foreach (var newPoint in thisSet)
                {
                    // Now we populate our results again with a new set of 
                    // lists for each existingItem and each newPoint
                    var newItem = existingItem.ToList();
                    newItem.Add(newPoint);
                    results.Add(newItem);
                }
            }
        }
    }

    return results;
}

用法示例:

private static void Main()
{
    var results = GetAllCombinations(0, 3, 5);

    foreach (var result in results)
    {
        Console.WriteLine(string.Join(" :: ", result.Select(p => $"{p.X} {p.Y}")));
    }

    Console.WriteLine("With a min value of 0 and max value of 3, " +
                        $"5 points generated {results.Count} results.");

    GetKeyFromUser("Done! Press any key to exit...");
}

输出量

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM