I'm struggling with this task. User is providing numbers L1 and L2. Add all odd numbers from range L1,L2 and all even numbers from this range and display the sums. I have to make it in 3 ways, using: for, while and do while loops. My for loop works perfectly, but while is displaying some higher scores.
import java.util.Scanner;
public class PPO4b {
public static void main(String[] args) {
Scanner value1Check = new Scanner(System.in);
System.out.println("Provide first value: ");
int value1 = value1Check.nextInt();
Scanner value2Check = new Scanner(System.in);
System.out.println("Provide second value: ");
int value2 = value2Check.nextInt();
int sumOdd = 0;
int sumEven = 0;
int i = 0;
while (i <= 0) {
if (i % 2 == 1) {
sumOdd = sumOdd i;
} else {
sumEven = sumEven i;
}
i = i 1;
}
System.out.println("Sum is equal to: " sumEven);
System.out.println("Sum is equal to: " sumOdd);
}
}
CodePudding user response:
With a little Math you can do this in O(1) time.
- For the sum of
1 thru n
values,n(n 1)/2)
will give the sum - Similarly for
k thru n
values,(n-k 1)(n k)/2
will give the sum of those values. - now consider a range of numbers like
2 3 4 5 6
. The total number of even values is3
which are2, 4, and 6
. This is true even if you have1 2 3 4 5 6 7
. - for any even value
s
, the next one lower is((s-1)
. So ifs = 4
would be3
- for any odd value
s
, the next lower one would be(s-1)|1
. So fors == 4
,(s-1) = 3 and 3|1 == 3
. TheOR
simply sets the low order bit to make the value odd or let it stay odd. - Similarly for any value
e
,e|1
will be either the same odd value or the next highest.
Now there is enough information to compute the sum of the even
and odd
values between s and e
.
For given int e and int s;
int totalSum = ((e s)*(e-s 1))/2;
e = (e|1);
s = (s-1)|1;
int evenCount = (e-s)/2;
int sumEven = ((e - s 1) * (evenCount))/2;
int sumOdd = totalSum - sumEven;
Here is how to verify it.
- compute the even and odd sums using an
IntStream
of the ranges, filtering out even and odd values as appropriate - next use the above methods for computing the same values.
- compare corresponding sums and report any discrepancies.
Random rnd = new Random();
for (int i = 0; i < 200000; i ) {
int s = rnd.nextInt(200) 100;
int e = rnd.nextInt(500) s;
int compEven = IntStream.rangeClosed(s, e)
.filter(r -> r % 2 == 0).sum();
int compOdd = IntStream.rangeClosed(s, e)
.filter(r -> r % 2 == 1).sum();
int totalSum = (e s) * (e - s 1) / 2;
e |= 1;
s = (s - 1) | 1;
int evenCount = (e - s 1) / 2;
int evenSum = ((e s) * evenCount) / 2;
int oddSum = totalSum - evenSum;
if (evenSum != compEven || oddSum != compOdd) {
System.out.println("Oops - sums don't match");
}
}
Note: depending on the range you may need to use long or BigInteger types to avoid overflow.