Reputation: 77
I have a problem, I have the correct(PART 1) and incorrect code (PART 2). I cant figure out why the incorrect code is incorrect.
the
static int sum = 0
part is the incorrect part of the code in PART 2. If that line of code is moved to the same location at PART 1. The code works.
if the range is from 10 to 20. PART 2 outputs an incorrect sum of 111. The sum should be 75. There are 3 possible combinations to get 111.
18 + 18 + correct sum
17 +19 + correct sum
16 + 20 + correct sum
Im guessing PART 2 passes through 18 + 18? but how?!
PART 1 Correct Code
ublic class SumOddRange {
public static boolean isOdd(int number){
if (number <= 0) {
return false;
}
return number % 2 != 0;
}
public static int sumOdd(int start, int end){
if ( (end < start) || (start < 0) || (end < 0) ){
return -1;
}
int sum = 0;
for (int i = start; i<=end; i++){
if (isOdd(i)){
sum +=i;
}
}
return sum;
}
PART 2 INCORRECT CODE
public class SumOddRange {
public static boolean isOdd(int number) {
if((number > 0) && (number % 2 != 0)) {
return true;
}
else {
return false;
}
}
static int startOne = 0;
static int sum = 0;
public static int sumOdd(int start, int end) {
if ((end >= start) && (end > 0) && (start > 0)) {
for (startOne = start; startOne <= end; startOne++) {
if (isOdd(startOne)) {
sum += startOne;
}
}
return sum;
} else
return -1;
}
Upvotes: 1
Views: 643
Reputation:
The problem is that you are using static
variables.
What does static
mean?
After creating a class, you can create instances (also called objects) of this class. This is what happens, when you use a command like
SumOddRange a = new SumOddRange();
SumOddRange b = new SumOddRange();
As you probably know, there are methods and variables in a class. These methods and classes can be seperated into
This means that some methods and variables do belong to the class, so all the instances of this class share this variable or method. This is what static
is used for. So if the class in the image above has a static attribute named staticAttributeName
, a.staticAttributeName
and b.staticAttributeName
have to be the same.
If a variable isn't static, this variable is not shared by the instances. All instances have their own instance of this variable. So although their name is the same, the values saved in the variables doen't have to be the same. So if the class in the image above has a non-static attribute named attributeName
, a.attributeName
and b.attributeName
doesn't have to be the same.
An example:
public class Add {
public static int sum = 0;
public static void addOne() {
sum = sum + 1;
}
}
public class Test {
public static void main(String[] args) {
Add a = new Add();
Add b = new Add();
a.addOne();
b.addOne();
System.out.println("a " + a.sum);
System.out.println("b " + b.sum);
}
}
As you can see, the variable sum
is static. This means that a.sum
and b.sum
are the same. In the main-method, we are calling the method addOne
two times, so the two outputs are "a 2" and "b 2".
public class Add {
public int sum = 0;
public void addOne() {
sum = sum + 1;
}
}
public class Test {
public static void main(String[] args) {
Add a = new Add();
Add b = new Add();
a.addOne();
b.addOne();
b.addOne();
System.out.println("a " + a.sum);
System.out.println("b " + b.sum);
}
}
We now have a non-static variable sum
in the class Add
.
addOne
one time, so the first output is "a 1".addOne
is called two times, so the output is "b 2".Solving the problem
public class Test {
public static void main(String[] args) {
SumOddRange s = new SumOddRange(); //Using class given in PART2 of question
SumOddRange t = new SumOddRange();
System.out.println(s.sumOdd(10,20));
System.out.println(s.sumOdd(10,20));
}
}
This class produces the outputs 75
and 150
. This is the case, because s
and t
use the same variable sum
, so the first time, the sum is correct, but the second calculation returns 75+sumOdd(10,20) = 75+75 = 150
as the result.
As we now know, the main problem is that the variable(s) are static
. This brings up the idea to just use non-static variables, which is the best idea here:
public class SumOddRange {
public boolean isOdd(int number) {
if((number > 0) && (number % 2 != 0)) {
return true;
}
else {
return false;
}
}
int startOne = 0;
int sum = 0;
public int sumOdd(int start, int end) {
sum = 0;
if ((end >= start) && (end > 0) && (start > 0)) {
for (startOne = start; startOne <= end; startOne++) {
if (isOdd(startOne)) {
sum += startOne;
}
}
return sum;
} else {
return -1;
}
}
}
Another option is to just reset the variable sum
before actually calculating the sum. The disadvantage of this approach is that you will not be able to access earlier results anymore:
static int startOne = 0;
static int sum = 0;
public static int sumOdd(int start, int end) {
sum = 0;
if ((end >= start) && (end > 0) && (start > 0)) {
for (startOne = start; startOne <= end; startOne++) {
if (isOdd(startOne)) {
sum += startOne;
}
}
return sum;
} else {
return -1;
}
}
Upvotes: 3