将数组中的连续偶数和连续奇数相加

时间:2015-08-28 18:53:34

标签: java arrays

我有一个代码可以对连续的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]

4 个答案:

答案 0 :(得分: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 :(得分:0)

你正在进入你的第一个for循环传递arr。在第一个for循环中,你输入第二个for循环传入arr第二次。这意味着你输入第二个for循环的次数与arr中的元素一样多,而第二个for循环中的arr每次都输入。

例如,如果arr.length()为2,则横向arr 3次。一旦进入你的外部for循环并且在你的内循环中两次(对于arr中的每个元素一次)。

其次,通过向你的arraylist添加奇数和偶数,除了重构arr之外你什么也没做,但是在arraylist而不是数组中。因此,返回arl.size()与返回arr.length()完全相同,这是已知的并且更容易做到。

尽管如此,这是我如何计算奇数和平均数的总和。我将两者都添加到不同的arraylists。您需要确切地知道您需要返回什么,因为您的描述已关闭。

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);

}

答案 2 :(得分:0)

玩了一段时间后,这是我的版本:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "authError",
    "message": "Invalid Credentials",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Invalid Credentials"
 }
}

我已发表评论,但仍有一些补充说明:

  1. 基本思路与@PKuhn相同,只检查了一些边缘情况(空数组,整数溢出)
  2. 我们不需要有一系列总和,我们只需要先前的总和,并用新计算的那个检查它的平价
  3. 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; } - 我们不需要计算全部金额,我们只需要总和的余额
  4. sum = (sum + n) & 1 - 只有在奇偶校验发生变化时我们才需要增加交换计数器,如果更改则xor帮助我们获得1,如果不是则为0,
  5. 以下是我使用的测试列表:

    s += (psum ^ sum) & f

答案 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");
    }