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;
}
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
Class methods and variables
Object methods and variables (object variables are most often called attributes)
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.
a: We are calling the method addOne one time, so the first output is "a 1".
b: The method 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;
}
}
Related
I have a basic code:
public class experiment {
public static void main(String[] args) {
System.out.println(experiment(80));
}
public static int experiment (int number) {
while (number > 10) {
number = number / 2;
return number;
} return -1;
}
}
It returns me 40.
So it means is not looping on the variable number.
I would like it to keep looping on number (80, 40, 20, 10), till it return 10.
Is there a way to do it without using the for loop?
Move the return out of the loop:
public static int experiment (int number) {
while (number > 10) {
number = number / 2;
}
return number;
}
If you need the -1 for a special case, you should check it before entering the loop:
public static int experiment (int number) {
if (number < 0) { // or some condition
return -1;
}
while (number > 10) {
number = number / 2;
}
return number;
}
BTW, start using a debugger, you can step through this kind of code and find the problem easily.
What wrong is that you put return number inside the while loop it will end the iteration and return the value of 40. So you have to,
public static int experiment (int number) {
while (number > 10) {
number = number / 2;
}
return number;
}
If you want all the numbers the loop has passed to print;
public static void experiment (int number) {
while (number > 10) {
number = number / 2;
System.out.println(number);
}
}
using recursion:
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(test.toTen(80));
}
public static int toTen(int k) {
if (k==10) {
return k;
}
else {
return toTen(k/2);
}
}
}
or simply edit the loop like so
while (k > 10) {
k = k / 2;
}
return k;
For this lab a cool number is any number that when divided by 3,4,5 & 6 will leave a remainder of 1. I have done the static boolean IsCoolNumber and I made a private int b to use as a counter but I have absolutely no idea where I would put for example a b++. Any help would greatly be appreciated.
Thanks in advance!
import static java.lang.System.*;
public class CoolNumbers
{
private int b=0;
public static boolean isCoolNumber( int num )
{
int x;
x = 6;
for(x = 6; x<num; x++)
{
if ((x%3==1) && (x%4==1) && (x%5 ==1) && (x%6 == 1))
return true;
}
return false;
}
public static int countCoolNumbers( int stop )
{
//add counter
}
public static void main( String[] args )
{
System.out.println( CoolNumbers.countCoolNumbers(250) + " cool numbers between 6 - " + 250);
//add more test cases
}
}
In isCoolNumber you don't need a loop, a single statement will do.
public static boolean isCoolNumber(int x) {
return (x % 3 == 1) && (x % 4 == 1) && (x % 5 == 1) && (x % 6 == 1);
}
To count the "cool numbers" add a simple loop in the currently empty countCoolNumbers( int stop ) method.
for (int i = start; i < stop; i++) {
if (isCoolNumber(i)) {
count++;
}
}
Write your method countCoolNumbersas below and try it...
public static int countCoolNumbers( int stop ){
boolean check=isCoolNumber(stop);
int num=0;
if(check==true){
num=stop;
}
num=0;
return num;
`}
public static void main( String[] args ) {
System.out.println( CoolNumbers.countCoolNumbers(250) + " cool numbers between 6 - " + 250);
//add more test cases
}
Then output will be:
0 cool numbers between 6 - 250
I have to write a program that takes a number from the user and then displays the prime factors of the number. This is the program I have so far:
public static void main(String[] args) {
int a = getInt("Give a number: ");
int i = 0;
System.out.println("Your prime factors are: " + primeFactorization(a, i));
}
public static int getInt(String prompt) {
int input;
System.out.print(prompt);
input = console.nextInt();
return input;
}
public static int primeFactorization(int a, int i) {
for (i = 2; i <= a ; i++) {
while (a % i == 0) {
a /= i;
}
}
return i;
}
}
I can't figure out how to get it to print out the list of numbers. Any help is appreciated.
You should return a List<Integer> not a single int, and there is no point in i being an argument. A correct method is
public static List<Integer> primeFactorization(int a) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 2; i <= a ; i++) {
while (a % i == 0) {
list.add(i);
a /= i;
}
}
return list;
}
While #Paul Boddington's answer is better in most cases (i.e. if you are using the values afterwards), for a simple program like yours, you could add all of the factors to a string and return the string. For example:
public static String primeFactorization(int a) {
String factors = "";
for (int i = 2; i <= a ; i++) {
while (a % i == 0) {
factors += i + " ";
a /= i;
}
}
return factors;
}
public class Program {
public static void main(String[] args) {
int lastFibo = 1; // ADDED TO check if last fib calculated is over 4000000
for (int i = 3; lastFibo <= 4000000; i = i + (i - 1)) {
lastFibo = fibo(i);
}
}
public static int fibo(int i) {
int total = 0;
if (i % 2 == 0) {
total += i;
return total;
}
return total;
}
}
The purpose of this code is to print the sum of even numbers in the fibonacci sequence who's values are less than 4 million. Using recursion the code returns a stack overflow error so it was recommended to iterate through the numbers. The difficulty encountered was knowing how to print the "total" variable. Scope articles are very basic and creating a static int total = 0 would return 0.
First, as pointed out by some comments: your for loop will not iterate the Fibonacci sequence. Second, the variable total exists only in the scope of your fibo method. So every time the method is called, total starts with the value 0.
Use the correct Fibonacci algorithm and add the return value of the fibo method up to calculate the sum:
public class Program {
public static void main(String[] args) {
int total = 0;
int previousValue = 0;
int currentValue = 1;
while (currentValue < 4_000_000) {
int nextPreviousValue = currentValue;
currentValue += previousValue;
previousValue = nextPreviousValue;
total += fibo(currentValue);
}
System.out.println(total);
}
public static int fibo(int i) {
if (i % 2 == 0) {
return i;
}
return 0;
}
}
4_000_000 is an integer literal you can use since Java 7 for the number 4000000. The purpose of the underscores is to make it better readable for humans. Programmatically there is no difference to using 4000000. For details see Primitive Data Types in The Java Tutorials.
Note: This first part of the question was related to a misunderstanding. I supposed that it was necessary to calculated up to fib(4000000).
You must use BigInteger otherwise you can't handle so big numbers. It is a number with many thousands of digits!
fib(4000000) results in a number with over 835k digits. It is not possible to handle it with int or long.
The class BigInteger (or the equivalent BigDecimal for decimal values) borns to handle such kind of problems.
Note: this is the answer to the question
Now that the question is more clear it is possible to give the correct answer.
public void printEvenFib() {
int i = 1;
int lastFib = 1;
int sum = 0;
while (lastFib <= 4000000) {
if (lastFib % 2 == 0) {
sum += lastFib;
}
i++;
lastFib = fib(i);
}
System.out.println(sum);
}
// Without recursion
public int fib(int n) {
if (n <= 2) {
return 1;
}
int fibo1 = 1;
int fibo2 = 1;
int fibo = 0;
for (int i = 3; i <= n; i++) {
fibo = fibo1 + fibo2;
fibo2 = fibo1;
fibo1 = fibo;
}
return fibo;
}
class Program2{
public static void main(String args[]){
int n1=0,n2=1,n3,total=0,i;
for(i=1;n3<4000000;++i){
n3=n1+n2;
if(n3%2==0)
total+=n3;
n1=n2;
n2=n3;
}
System.out.println("total is "+total);
}
}
I'm having a problem with my code here. I'm trying to find all multiples of 3 and 5 up to one thousand and add them all up, and at the end when I try to output the sum, java gives me a 'cannot find symbol' error. Can anybody figure out what's wrong here?
public class Problem1
{
public static void main(String []args)
{
//int sum1;
//int sum2;
int finalSum;
for(int i = 0; i < 1000; i++)
{
if(i % 3 == 0)
{
int sum;
sum += i;
}
else if(i % 5 == 0)
{
int sum;
sum += i;
}
}
System.out.println(sum);
}
}
Java has block scoping, which means that the sum declared in between {}s (braces) is not visible outside. Declare sum once, outside of the for loop.
public class Problem1
{
public static void main(String []args)
{
int sum = 0;
for(int i = 0; i < 1000; i++)
{
if(i % 3 == 0)
{
sum += i;
}
else if(i % 5 == 0)
{
sum += i;
}
}
System.out.println(sum);
}
}
you can not declare sum in loop.Then it is local to that method.
It's because you're "creating" sum inside the if statements which limits their scope - they're created within the if blocks and destroyed at the next closing brace.
Get rid of those two int sum; lines inside the if blocks and put it at the top of the function (where the rather useless finalSum is). Or just use finalSum everywhere.
You can also combine the if conditions for shorter code:
public class Problem1
{
public static void main(String []args)
{
int finalSum = 0;
for(int i = 0; i < 1000; i++)
if((i % 3 == 0) || (i % 5 == 0))
finalSum += i;
System.out.println(finalSum);
}
}
you have defined the variable sum inside the the if/else which limits the scope of the variable.System.out.print() statement is outside the scope of sum hence you are getting the error.
public class Problem1
{
public static void main(String []args)
{
int sum=0;
for(int i = 0; i < 1000; i++)
{
if(i % 3 == 0)
{
sum += i;
}
else if(i % 5 == 0)
{
sum += i;
}
}
System.out.println(sum);
}
}