簡體   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