[英]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.