更改变量会产生无限循环

时间:2019-02-21 06:39:52

标签: c#

我最近一直在学习Python,但是最近想做一个涉及2D数组的项目,所以我决定切换到C#(如果我的代码很糟糕,请您抱歉)

基本上,我正在编写一个为我做填字游戏的程序。

  • 我有i遍历顶部/底部
  • 我有j从左到右迭代

我发现想要的第一个字母i-让我们称它为“关键字”

现在,我需要查看周围的所有8个空格。如果i/j的位置是[1,2],那么我首先看的是[0,2]

在我的代码中,我想将i1更改为0,然后打印(如果这是正确的字母),第二个字母是:[0,2]

一旦我将i1更改为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();
            }
        }
    }
}    

我将其设置为:

  • keyletter =“ a”
  • keyletter2 =“ b”

Loop problem picture

3 个答案:

答案 0 :(得分:0)

问题出在语句上

// if(keyLetter2 ==填字游戏[i-1,j])

如果矩阵类似于

a b c

d e f

我是我

并假设您要搜索模式“ ba”,那么显然您将寻找b,因此i将为0,j将为1。现在,您将要做(i-1),这将是- 1(没有负索引),因此出现错误。

执行此操作的最佳方法是检查i或j是否已经为0。如果它们是0,那么您不需要i-1或j-1,则可以像 “ if(i!= 0) 然后 if(keyLetter2 ==填字游戏[i-1,j]) ... “

答案 1 :(得分:0)

我看不到任何无限循环,但是运行时异常(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;
        }
      }

答案 2 :(得分:0)

我将采用稍微不同的方法,即将“邻居搜索”委托给一个辅助方法。您可以将数组,应搜索其邻居的单元格以及要搜索的值传递给此方法。

因为一个单元格项是由两个整数坐标定义的,并且由于存在一个Point结构,我们可以使用它具有两个整数属性(XY),所以我用它来表示数组中的一个单元格。

辅助函数通过确定要搜索其邻居的像元周围的XY的最小值,方法是从其1和{{ 1}}值。然后,我们需要确保该结果不小于X,以确保我们停留在数组的范围内。

同样,我们添加Y以获得最大值,并确保它不大于数组的上限。

最后,我们在0中返回匹配项列表(如果找到):

1

现在,我们可以在现有代码中使用此辅助方法:

List<Point>

输出

enter image description here