2017-04-10 130 views
0

我想爲我的解決方案For循環轉換爲Foreach循環。而For循環產生我想要的輸出(見下文)。的foreach生成以下錯誤:訪問數組項目:「For」循環工作和「Foreach」給出System.IndexOutOfRangeException

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; 
     } 
+0

您正在使用數組「a」和數組「b」中的值來索引數組,這就是問題所在。你想要的是 - > bool result = false; (i + j == v) result = true;如果(i + j == v) 結果= true;如果(i + j == v) 結果=真;如果(i + j == v) 結果=真; } } 返回結果; –

+0

另請參見:只在'if()'條件中'返回true;'。一旦你找到了好的結果,這將節省你做額外的工作。 –

回答

3

他們之間的區別是,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; 
     } 
.... 
+0

另外:只是'返回true;'而不是設置結果值。這將算法從'n2'降到'n log(n)'。 –

+0

@JoelCoehoorn雖然準確,但它超出了 –

1

您實現在foreach
foreach (int i in a)
i完全錯誤的是陣列的價值。
因此,如果a[0]的值爲10,但是您的數組大小小於10,則您在if語句中實際上調用a[10]。你將有out of bound exception

只是使用 if (i + j == v)在你的if語句應該工作。

1

你可以得到這個下降到一個班輪:

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

如果序列中有任何成員,則Any()方法返回true,否則返回falseAny()調用中的其餘代碼允許您在某些條件謂詞上過濾序列,因此只有在過濾器「存活」的情況下才會變爲真。

爲條件,我們再次使用Any()方法與b序列,有效地每個可能的組合,從ab比較,就如同當初代碼執行,結果限制爲配合我們a+b=v條件的項目。 Where()也可以爲此工作,但Any()更好,因爲它會在第一場比賽中停止。

我寧願爲此使用.Intersect(),這可能導致代碼更容易理解,但是。 Intersect()要求您定義整個IEqualityComparer類而不是簡單的委託。

+0

這個問題的範圍,你能解釋一下它是如何工作的嗎? –