2015-08-28 160 views
-1

我有一個代碼,將連續的even數字和連續的odd數字相加,然後將它們添加到arraylist。應重複此過程,直到列表中不再有連續的奇數或偶數。然後返回arraylist的大小。數組中連續的偶數和連續的奇數

我使用嵌套for循環,問題是循環檢查相同index這是沒有意義的。

這裏是我的代碼:

public static int SumGroups(int[] arr) { 
    ArrayList<Integer> arl = new ArrayList<Integer>(); 
    int even = 0, odd = 0; 
    for (int i = 0; i < arr.length; i++) { 
     for (int j = i + 1; j < arr.length; j++) { 
      if (arr[i] % 2 == 0) { 
       even += arr[i]; 
       if (arr[j] % 2 == 0) { 
        even += arr[j]; 
       } else { 
        arl.add(even); 
        even = 0; 
        break; 
       } 
      } else { 
       odd += arr[i]; 
       if (arr[j] % 2 != 0) { 
        odd += arr[j]; 
       } else { 
        arl.add(odd); 
        odd = 0; 
        break; 
       } 
      } 
     } 
    } 
    return arl.size(); 
} 

我的問題是: 如何防止環路從檢查相同指數? 換句話說,如何讓我的代碼總和連續的偶數和連續的奇數?

輸入:

int arr[]={2, 1, 2, 2, 6, 5, 0, 2, 0, 5, 5, 7, 7, 4, 3, 3, 9}; 

輸出:

6 // [2, 1, 10, 5, 30, 15] 
+0

我更新了帖子來解釋我的問題 –

+0

您能否提供樣本輸入和期望的輸出? –

+0

@Lashane更新! –

回答

4
I think the following code should solve the problem, if you do not want to output the size simply return `sums` instead of `sums.size()` 

public static int sumGroupsRecursively(int[] arr) { 
     List<Integer> numbersToSum = IntStream.of(arr).boxed().collect(Collectors.toList()); 
     List<Integer> currentSumList = sumSublist(numbersToSum); 
     List<Integer> nextSumList = sumSublist(currentSumList); 

     while (currentSumList.size() != nextSumList.size()) { 
      currentSumList = nextSumList; 
      nextSumList = sumSublist(currentSumList); 
     } 

     return nextSumList.size(); 
    } 


    public static List<Integer> sumSublist(List<Integer> list) { 
     int current = list.get(0); 
     int currentSum = 0; 
     List<Integer> sums = new ArrayList<>(); 
     for (int i = 0; i < list.size(); i++) { 
      if (current % 2 == list.get(i) % 2) { 
       currentSum += list.get(i); 
      } else { 
       sums.add(currentSum); 
       current = list.get(i); 
       currentSum = current; 
      } 
     } 
     sums.add(currentSum); 
     return sums; 
    } 

如果你需要做的這一個功能我會阻止,因爲這是很難讀你可以使用這樣的代碼。

public static Integer sumSublist(int[] arr) { 
    List<Integer> sums = new ArrayList<>(); 
    sums.add(0); 
    int i = 0; 
    while (i < arr.length - 1) { 
     int current = arr[i]; 
     int currentSum = 0; 
     while (current % 2 == arr[i] % 2) { 
      currentSum += arr[i]; 
      if (i >= arr.length - 1) { 
       break; 
      } 
      i++; 
     } 
     if (currentSum % 2 == sums.get(sums.size()-1) % 2) { 
      sums.set(sums.size() - 1, sums.get(sums.size()-1) + currentSum); 
     } else { 
      sums.add(currentSum); 
     } 
    } 
    return sums.size(); 
} 
+1

如果這解決了你的問題,考慮標記答案爲 – PKuhn

0

您正在輸入您的第一個for循環傳入arr。在第一個for循環中,第二次輸入第二個for循環傳遞給arr。這意味着您每次輸入第二個for循環的次數與arr中的元素和第二個for循環中的橫向arr次數相同。例如,如果arr.length()是2,那麼您會橫向放置3次arr.length()。一旦進入外循環,並在內循環中進行兩次(對於arr中的每個元素一次)。第二,通過在您的數組列表中添加奇數和偶數,您除了重構arr之外無所作爲,而是以數組而不是數組。因此,返回arl.size()與返回已知的arr.length()完全相同,而且更容易完成。

儘管如此,這裏是我將如何計算奇數和平均值的總和。我將這兩個添加到不同的數組列表中。您需要明確您需要返回的內容,因爲您的描述已關閉。

public void test(){ 

int[] arr = new int[5]; 
arr[0] = 1; 
arr[1] = 2; 
arr[2] = 3; 
arr[3] = 4; 
arr[4] = 5; 

int testOfEven = 6; 
int testOfOdd = 9; 
int sumOfEven = 0; 
int sumOfOdd = 0; 

ArrayList evens = new ArrayList<Integer>(); 
ArrayList odds = new ArrayList<Integer>(); 

for(int i = 0; i < arr.length; i++) 
{ 
    if ((arr[i]%2) == 0) 
    { 
    evens.add(arr[i]); 
    sumOfEven += arr[i]; 
    } 
    else 
    { 
    odds.add(arr[i]); 
    sumOfOdd += arr[i]; 
    } 
} 

assertEquals(testOfEven, sumOfEven); 
assertEquals(testOfOdd, sumOfOdd); 

}

0

玩了一段時間後,這裏是我的版本:

public static int SumGroups(final int[] arr) { 
    if (arr.length > 0) { 
     int n, sum, psum; 
     psum = sum = n = arr[0] & 1; // parity of first number in sequence 
     int s = 1; // at least one element in array 
     int f = 0; // discard first parity change 
     for (int i = 1; i < arr.length; i++) { 
      if (n == (arr[i] & 1)) { 
       sum = (sum + n) & 1; // both even or odd, just increase sum 
      } else { 
       s += (psum^sum) & f; // compare sums parity 
       psum = sum; // store current sum's parity 
       sum = n = arr[i] & 1; // new first number in sequence 
       f = 1; // do not discard sums parity next time 
      } 
     } 
     s += (psum^sum) & f; // array ended, check parity of last sum 
     return s; 
    } 
    return 0; 
} 

我已經把意見,但還是有些其他注意事項:

  1. 基本思路是與@PKuhn相同,只是檢查了一些邊緣情況(空數組,整數溢出)
  2. 我們並不需要有資金的陣列,我們只需要以前的總和,並檢查它的平價新計算
  3. sum = (sum + n) & 1 - 我們並不需要計算整個總之,我們只需要和的奇偶性
  4. s += (psum^sum) & f - 我們需要增加交換櫃檯只有平價發生變化,XOR幫助我們拿到1,如果更改,否則爲0

這裏是我使用的測試列表:

Assert.assertEquals(6, SumGroups(new int[] { 2, 1, 2, 2, 6, 5, 0, 2, 0, 5, 5, 7, 7, 4, 3, 3, 9 })); 
    Assert.assertEquals(6, SumGroups(new int[] { 0, 0, 0, 0, 2, 1, 2, 2, 6, 5, 0, 2, 0, 5, 5, 7, 7, 4, 3, 3, 9 })); 
    Assert.assertEquals(1, SumGroups(new int[] { 2, 3, 3 })); 
    Assert.assertEquals(1, SumGroups(new int[] { 2 })); 
    Assert.assertEquals(1, SumGroups(new int[] { 2, 2 })); 
    Assert.assertEquals(1, SumGroups(new int[] { 2, 3, 3, 3, 3, 2 })); 
    Assert.assertEquals(2, SumGroups(new int[] { 3, 2, 2 })); 
    Assert.assertEquals(2, SumGroups(new int[] { 1, 3, 3, 2, 2 })); 
    Assert.assertEquals(2, SumGroups(new int[] { 1, 2, 3, 3, 2, 3, 3, 2 })); 
    Assert.assertEquals(1, SumGroups(new int[] { 3, 3, 2, 2 })); 
    Assert.assertEquals(1, SumGroups(new int[] { Integer.MAX_VALUE, Integer.MAX_VALUE })); 
    Assert.assertEquals(1, SumGroups(new int[] { Integer.MAX_VALUE, Integer.MAX_VALUE, 2 })); 
    Assert.assertEquals(1, SumGroups(new int[] { Integer.MAX_VALUE, Integer.MAX_VALUE, 3 })); 
0

public void findEvenOdd(int a []){

Boolean flip = false; 
    int sum = 0, i, m = 0; 
    for (i = 0; i < a.length; i++) { 
    if (flip) { 
    System.out.print(sum + "\t"); 
    sum = a[i]; 
    flip = !flip; 
    if (i + 1 < a.length && (a[i] % 2 != a[i + 1] % 2)) 
    flip = !flip; 
    m++; 
    } else { 
    sum += a[i]; 
    if (i + 1 < a.length && (a[i] % 2 != a[i + 1] % 2)) 
    flip = !flip; 
    m++; 
    } 

    } 

    if(m!=a.length-1) 
    System.out.print(a[a.length-1] + "\t"); 
    } 
+0

當給出答案時,最好給出[一些解釋爲什麼你的答案](http://stackoverflow.com/help/how-to-answer)是這一個。 –

+0

對問題的回答。不要添加複製粘貼的代碼 –