簡體   English   中英

數組中連續的偶數和連續的奇數之和

[英]Sum consecutive even numbers and consecutive odd numbers in an array

我有一個代碼,將連續的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]
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();
}

您正在輸入第一個for循環傳遞arr。 在第一個for循環內,您輸入第二個for循環,第二次傳入arr。 這意味着您每次輸入第二個for循環的次數就等於第二個for循環中arr和橫向arr中的元素的次數。

例如,如果arr.length()為2,則將橫向arr 3次。 在外部for循環中一次,在內部循環中兩次(對於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);

}

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

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;如果沒有更改,則xor可以幫助我們獲得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 }));

公共無效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");
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM