简体   繁体   English

猜测可能组合的方法

[英]Method to guess possible combination

For practice I want to write a program that will guess random positions of x and y. 为了练习,我想编写一个程序来猜测x和y的随机位置。 For example the first point would be 例如,第一点是

int x = 0;
int y = 0;

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

Then from that random point I will add the another random value to x and y to have a second point. 然后从那个随机点开始,我将另一个随机值加到x和y上得到第二个点。 However I want to go back to find those points randomly. 但是,我想返回以随机找到这些点。

To make the points: 提出要点:

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));
}

Now I wish to guess those random points almost as if I did not have them stored in a list. 现在,我想猜测那些随机点,就好像我没有将它们存储在列表中一样。 Because each new point relies on its predecessor I assume some sort of recursion would be necessary. 因为每个新点都依赖于它的前任,所以我认为某种递归是必要的。 Almost like a brute force guessing application that will find those points. 几乎就像蛮力猜测应用程序一样,可以找到那些要点。 I am having trouble completing the method that would be able to guess every possible point given a number of desired points. 我在完成该方法时遇到了麻烦,该方法能够在给定多个所需点的情况下猜测每个可能的点。

This is what I have thus far to find the rounds: 到目前为止,这是我找到的回合:

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();
        }
    }
}

I am trying to randomly generate points as shown above and then guess them based on a hashed value representing all of those points together. 我试图随机生成点,如上所示,然后根据代表所有这些点的哈希值猜测它们。

This is what im expecting to see: 我期望看到的是:

If only guessing two points 如果只猜两点

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

And so on until all possibilities of point one and point two are guessed 依此类推,直到猜到了第一点和第二点的所有可能性

I'm not sure if this is exactly what you're looking for, but one way to get all those combinations is to use nested for loops: 我不确定这是否正是您要寻找的东西,但是获取所有这些组合的一种方法是使用嵌套的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}");
            }
        }
    }
}

Output 输出量

在此处输入图片说明


You were asking about a solution that would allow a variable number of points to be passed in. This is fairly simple to do - you just keep a List<List<Point>> of the results, and on each iteration you generate a list of possible point values (16 possible values when min is 0 and max is 3), and then generate a new list for every item in the existing results for each Point in the new set. 您在问一个解决方案,该方法允许传递可变数量的点。这非常简单-您只需保留结果的List<List<Point>> ,并在每次迭代时生成一个列表即可可能的点值(最小为0且最大为3时为16个可能的值),然后为新集中每个Point的现有结果中的每个项目生成一个新列表。

The problem is the size of the result set. 问题是结果集的大小。 Since a single point has 16 possible combinations of X and Y if we have a min value of 0 and a max value of 3, then for each additional point, we raise 16 to that power. 由于如果我们的最小值为0且最大值为3,则单个点具有X和Y的16种可能组合,因此对于每个其他点,我们将16提升至该乘方。 So for 10 points, there are over a billion combinations. 因此,对于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;
}

Example usage: 用法示例:

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...");
}

Output 输出量

在此处输入图片说明

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

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