我最近一直在学习Python,但最近我想做一个涉及2D数组的项目,所以我决定转到C# (如果我的代码很差的话)。
基本上我在写一个程序为我做一个纵横字谜游戏。
i在顶部/底部迭代j从左到右循环我发现第一个字母i想要-让我们称之为“关键字母”。
现在我需要查看它周围的所有8个空间。如果i/j的位置是[1,2],我首先要看[0,2]。
在我的代码中,我想将i从1改为0,并打印(如果这是正确的字母),第二个字母是:[0,2]
一旦我将i从1改为0并尝试打印,它就会吐出一百万次,然后卡住。
public static void Main(string[] args)
{
string keyLetter = "g";
string keyLetter2 = "b";
string[,] crossword = new string[,]
{
{ "a", "b", "c", "d" },
{ "e", "f", "g", "h" },
{ "a", "e", "b", "c" },
{ "i", "j", "k", "l" }
};
for (int i = 0; i < crossword.GetLength(0); i++)
{
for (int j = 0; j < crossword.GetLength(1); j++)
{
if (keyLetter == crossword[i, j])
{
Console.Write(keyLetter + " is [" + i + ", " + j + "]");
Console.WriteLine();
Console.WriteLine();
Console.Write("i is: " + i);
Console.WriteLine();
Console.Write("j is: " + j);
Console.WriteLine();
if (keyLetter2 == crossword[i - 1, j])
{
// i--;
Console.Write("[i/j] position for " + keyLetter2 + " is [" + i +
", " + j + "]");
}
else if (keyLetter2 == crossword[i + 1, j])
{
Console.Write("[i/j] position for " + keyLetter2 + " is [" + i +
", " + j + "]");
}
/*
else if (keyLetter2 == crossword[i + 1, j - 1])
{
Console.Write("[i/j] position for " + keyLetter2 + " is [" + i +
", " + j + "]");
}
else if (keyLetter2 == crossword[i, j - 1])
{
Console.Write("[i/j] position for " + keyLetter2 + " is [" + i +
", " + j + "]");
}
else if (keyLetter2 == crossword[i - 1, j - 1])
{
Console.Write("[i/j] position for " + keyLetter2 + " is [" + i +
", " + j + "]");
}
else if (keyLetter2 == crossword[i + 1, j + 1])
{
Console.Write("[i/j] position for " + keyLetter2 + " is [" + i +
", " + j + "]");
}
else if (keyLetter2 == crossword[i, j + 1])
{
Console.Write("[i/j] position for " + keyLetter2 + " is [" + i +
", " + j + "]");
}
else if (keyLetter2 == crossword[i - 1, j + 1])
{
Console.Write("[i/j] position for " + keyLetter2 + " is [" + i +
", " + j + "]");
}*/
Console.WriteLine();
}
}
}
} 我把它设置成:
发布于 2019-02-21 07:18:38
问题在于这句话
//if (keyLetter2 == crosswordi-1,j)
在这里,如果矩阵是
“
A、b、c
D、e、f
i
“
假设您想要搜索模式"ba",那么很明显,您将查找b,因此I将为0,j将为1。现在,您将执行(i-1),即-1(没有负索引),因此出现了错误。
这样做的最佳方法是检查i或j是否已经为0。如果它们为0,则不需要i-1或j-1,并且可以类似于“if(i!=0)然后If (keyLetter2 == crosswordi-1,j) .”
发布于 2019-02-21 07:20:51
我看不到任何无限循环,但运行时异常(IndexOutOfRangeException)在
if (keyLetter2 == crossword[i-1, j]) {...} // if i == 0
...
else if (keyLetter2 == crossword[i+1, j]) {...} // if i == crossword.GetLength(0) - 1让我们消除这些异常,并浏览循环:
for (int i = 0; i < crossword.GetLength(0); ++i)
for (int j = 0; j < crossword.GetLength(1); ++j)
if (keyLetter == crossword[i, j]) {
// Keep you messages being readable with a help of string interpolation - $""
Console.WriteLine(string.Join(Environment.NewLine,
$"{keyLetter} is [{i}, {j}]",
""
$"i is: {i}",
""
$"j is: {j}",
""
));
// Do not repeat yourself: if you want 4 neighbors to test
for (int neighbor = 0; neighbor < 4; ++neighbor) {
int ii = i + (neighbor % 2) * (neighbor - 1);
int jj = j + (1 - neighbor % 2) * (neighbor - 1);
// Check indexes ii, jj before addressing [ii, jj]
if (ii >= 0 && ii < crossword.GetLength(0) &&
jj >= 0 && jj < crossword.GetLength(1) &&
keyLetter2 == crossword[ii, jj]) {
Console.Write($"[i/j] position for {keyLetter2} is [{i}, {j}]");
// In case we want at most one neighbor; comment it out if we want all of them
break;
}
}
}如果您有8 (而不是4)邻居要检查
...
bool found = false;
for (int ii = Math.Max(0, i - 1); ii <= Math.Min(i + 1, crossword.GetLength(0)) && !found; ++ii)
for (int jj = Math.Max(0, j - 1); jj <= Math.Min(j + 1, crossword.GetLength(0)) && !found; ++jj) {
if ((ii != i || jj != j) && keyLetter2 == crossword[ii, jj])) {
Console.Write($"[i/j] position for {keyLetter2} is [{i}, {j}]");
// In case we want at most one neighbor; comment it out if we want all of them
found = true;
}
}发布于 2019-02-24 18:56:19
我将采取一种稍微不同的方法,即将“邻居搜索”委托给助手方法。您可以将数组、应该搜索其邻居的单元格以及正在搜索的值传递给此方法。
因为一个单元格项是由两个整数坐标定义的,而且由于有一个现有的Point结构,我们可以使用它具有两个整数属性(X和Y),所以我使用它来表示数组中的一个单元格。
辅助函数的工作方式是确定单元格周围X和Y的最小值,通过从X和Y值中减去1来搜索它们的邻居。然后,我们需要确保这个结果不少于0,以确保我们保持在数组的范围内。
同样,我们添加1以获得最大值,并确保它不大于数组的上限。
最后,我们返回List<Point>中的匹配列表(如果有的话)
public static List<Point> GetNeighborMatches(string[,] grid, Point item, string valueToFind)
{
var result = new List<Point>();
// if our grid is empty or the item isn't in it, return an empty list
if (grid == null || grid.Length == 0 ||
item.X < 0 || item.X > grid.GetUpperBound(0) ||
item.Y < 0 || item.Y > grid.GetUpperBound(1))
{
return result;
}
// Get min and max values of x and y for searching
var minX = Math.Max(item.X - 1, 0);
var maxX = Math.Min(item.X + 1, grid.GetUpperBound(0));
var minY = Math.Max(item.Y - 1, 0);
var maxY = Math.Min(item.Y + 1, grid.GetUpperBound(1));
// Loop through all neighbors to find a match
for (int x = minX; x <= maxX; x++)
{
for (int y = minY; y <= maxY; y++)
{
// Continue looping if we're on the 'item'
if (x == item.X && y == item.Y) continue;
// If this is a match, add it to our list
if (grid[x, y] == valueToFind) result.Add(new Point(x, y));
}
}
// Return all the matching neighbors
return result;
}现在,我们可以在现有代码中使用此助手方法:
public static void Main(string[] args)
{
string keyLetter = "g";
string keyLetter2 = "b";
string[,] crossword = new string[,]
{
{ "a", "b", "c", "d" },
{ "e", "f", "g", "h" },
{ "a", "e", "b", "c" },
{ "i", "j", "k", "l" }
};
for (int i = 0; i < crossword.GetLength(0); i++)
{
for (int j = 0; j < crossword.GetLength(1); j++)
{
if (keyLetter == crossword[i, j])
{
// we found a match for our first letter!
Console.WriteLine("The first value (" + keyLetter + ") is at [" +
i + ", " + j + "]");
// get neighboring matches for keyLetter2
List<Point> matches = GetNeighborMatches(crossword,
new Point(i, j), keyLetter2);
// Output our matches if we found any
if (matches.Any())
{
foreach (var match in matches)
{
Console.WriteLine("The second value (" + keyLetter2 +
") is at [" + match.X + ", " + match.Y + "]");
}
}
else
{
Console.WriteLine("No match was found for '" + keyLetter2 +
"' near [" + i + ", " + j + "]");
}
}
}
}
}输出

https://stackoverflow.com/questions/54800760
复制相似问题