访问数组项:"For" 循环有效,"Foreach" 给出 System.IndexOutOfRangeException

Accessing Array Items: "For" loop works and "Foreach" gives System.IndexOutOfRangeException

我正在尝试将 For 循环转换为 Foreach 循环以用于我的解决方案。 For Loop 为我生成了所需的输出(见下文)。 Foreach 生成以下错误:

System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'

public static bool sumOfTwo(int[] a, int[] b, int v)
        {
            bool result = false;
            for (int i = 0; i < a.Length; i++)
            {
                for (int j = 0; j < b.Length; j++)
                {
                    if (a[i] + b[j] == v)
                    {
                        result = true;
                    }
                }
            }
           return result;
         }

和我的 foreach 实现:可能出了什么问题?

public static bool sumOfTwo(int[] a, int[] b, int v)
        {
            bool result = false;
            foreach (int i in a)
            {
                foreach (int j in b)
                {
                    if (a[i] + b[j] == v)
                    result = true;
                }
            }
            return result;
        }

你的实现完全错误 foreach
foreach (int i in a)
i 是数组的值。
因此,如果 a[0] 的值为 10 但您的数组大小小于 10,那么您实际上是在 if 语句中调用 a[10] 。您将有 out of bound exception

随便用 if (i + j == v) 在你的 if 语句中应该有效。

它们之间的区别是 for (int i = 0; i < a.Length; i++) 给你一个索引,而 foreach (int i in a) 给你实际值。

例如:如果您有一个数组 int[] a = {10, 0, 11},您将得到以下内容:

for (int i = 0; i < a.Length; i++)
    Console.WriteLine(a[i])

// a[0] = 10
// a[1] = 0
// a[2] = 11

foreach (int i in a)
    Console.WriteLine(a[i])

// a[10] = IndexOutOfRangeException
// a[0]  = 10
// a[11] = IndexOutOfRangeException

因此,与其在代码的第二位中使用数组访问器,不如直接使用 i & j 的值:

....
        foreach (int j in b)
        {
            if (i + j == v)
                result = true;
        }
....

你可以把它简化为一行:

public static bool sumOfTwo(int[] a, int[] b, int v)
{
    return a.Any(A => b.Any(B => B + A == v));
}

Any() 方法 returns true 当且仅当一个序列有任何成员,否则 falseAny() 调用中的其余代码允许您在某些条件谓词上过滤序列,因此只有在 "survives" 过滤器有任何内容时您才会得到 true。

对于条件,我们再次使用 Any() 方法和 b 序列,有效地比较来自 ab 的每个可能组合,就像原来的一样代码会,并将结果限制为符合我们的 a+b=v 条件的项目。 Where() 也适用于此,但 Any() 更好,因为它会在第一场比赛中停止。

我更愿意为此使用 .Intersect(),这可能会使代码更容易理解,但是 .Intersect() 要求您定义一个整体 IEqualityComparer class 而不是简单的委托。