Recursion - Exception in thread "main" java.lang.StackOverflowError - java

I am required to write a recursive method. I have written the code to perform the task without recursion. I am getting the error Exception in thread "main" java.lang.StackOverflowError at Exercise13r.recursion(Exercise13r.java:29). Code is... to enter a number then if result is even, divide by 2, if result is odd, multiply by 3 and subtract 1. Obviously I am looping but not sure why. Any assistance would be appreciated.
import java.util.Scanner;
public class Exercise13r
{
public static void main(String[] args)
{
// Initialize variables
long number = 0;
Scanner in = new Scanner(System.in);
System.out.println ("Enter a starting number: ");
number = in.nextInt ();
System.out.println ("Your starting number is: " + number);
if (number != 1)
{
recursion(number);
}
}
public static void recursion(long n)
{
if (n % 2 == 0)
{
recursion(n/2);
}
else
{
recursion(n*3-1);
}
System.out.println ("number: " + n);
return;
}
}

Your base case if (number != 1) needs to be inside the definition of the function so that it actually knows when to stop. Right now your program eventually reduces to calling recursion(1) and your function will still call itself recursively (what else can it do?) so it ends up calling recursion(2) which leads to recursion(1) again and so on.
Note that this becomes apparent if you move System.out.println ("number: " + n); before the recursive calls. Since you have infinite recursion it never gets around to printing anything preventing you from seeing the problem.
Here is a minimal working example:
class Exercise13r {
public static void main(String[] args) {
recursion(12);
}
public static void recursion(long n) {
System.out.println ("number: " + n);
if (n != 1) {
if (n % 2 == 0) {
recursion(n/2);
} else {
recursion(n*3-1);
}
}
}
}
Output:
number: 12
number: 6
number: 3
number: 8
number: 4
number: 2
number: 1

Related

Printing ArrayList from a separate main class Java

I have an Assignment that has many questions and the only ones I seem to be having trouble with are the ones with ArrayLists. I need to use a separate main method to enter and print out information.
This is my class
import java.util.ArrayList;
public class HailstoneSequence {
private int n;
public HailstoneSequence(int n) {
this.n = n;
}
public double getn() {
return n;
}
public static ArrayList<Integer> getHailstoneSequence(int n){
ArrayList<Integer> list = new ArrayList<Integer>();
//int i = 0;
while (n != 1);
for (int s : list) {
try {
if(n == 1) break;
if(n % 2 == 0) {
System.out.println(n + " is even, so I take half: " + (n / 2));
}
else
System.out.println(n + " is odd, so I make 3n+1: " + ((n * 3)+1));
// i++;
}
catch (Exception error) {
while (n <= 1) {
System.out.println("You did not enter a valid positive, greater than 1 integer. Please try again: ");
System.out.println();
}
}
}
return list;
}
}
and this is the main class (which does not work)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class TestHailstoneSequence {
#SuppressWarnings("resource")
public static void main(String[]args){
Scanner input = new Scanner(System.in);
System.out.println("The Hailstone Sequence takes a number and if it odd it multiples it by 3 and adds 1,"
+ "\nit divides it by 2 and carries on until it reaches 1. \nPlease enter a positive number"
+ " (greater than 1) to generate the Hailstone Sequence: ");
int n = input.nextInt();
HailstoneSequence aHailstoneSequence = new HailstoneSequence(n);
System.out.println(Arrays.toString(aHailstoneSequence.list));
}
}
Please help me understand how to print out the results
You declared getHailstoneSequence method as static one you should call it and store to a variable if you need in another operation and printing like this:
ArrayList<Integer> list = HailstoneSequence.getHailstoneSequence(n);
System.out.println(list);
For your current case the main method will look something like this:
import java.util.Scanner;
public class TestHailstoneSequence {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("The Hailstone Sequence takes a number and if it odd it multiples it by 3 and adds 1,"
+ "\nit divides it by 2 and carries on until it reaches 1. \nPlease enter a positive number"
+ " (greater than 1) to generate the Hailstone Sequence: ");
int n = input.nextInt();
input.close(); // do not forget to close the resource
// if you use static method in your HailstoneSequence class you can remove
// field with name "n" from that class and you don't need to create an object in this case
// Also I'd rename the class from HailstoneSequence to something like HailstoneSequenceCalculator
System.out.println(HailstoneSequence.getHailstoneSequence(n));
}
}

Java print the recursion in main method

I was wondering when I tried to print the value of recursion in main, the answer was:
Enter the number: 1
2The result is:
How to make the number 2 to the front like,
The result is: 2
import java.util.Scanner;
public class Question4Final {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Enter the number: ");
int a = scan.nextInt();
System.out.printf("The result is: ", multiplication(a));
}
public static int multiplication(int a) {
if (a == 5) {
int multiply = 10 * 6 * 2;
System.out.print(multiply);
} else if (a == 4) {
int multiply2 = 6 * 2;
System.out.print(multiply2);
} else if (a == 1) {
System.out.print("2");
}
return a;
}
}
To call the method:
System.out.printf("The result is: ", multiplication(a));
first the arguments must be evaluated, so multiplication(a) is executed before System.out.printf("The result is: ", multiplication(a)). Since multiplication(a) prints something, that printing takes place before "The result is:" is printed.
You should change multiplication(a) to simply return the result without printing it. Then use System.out.println("The result is: " + multiplication(a)) to print the result.
Note the you have to change the value returned by multiplication(a), since currently you return a, which is not the value printed by that method.
You have 2 issues in your code.
First is you are printing the value of 'multiply' in your static method :
public static int multiplication(int a){
System.out.print(multiply);
That is a reason why it is printing 2 before the statement :
2The result is:
2nd issue is you are calling the method multiplication in the print statement :
System.out.printf("The result is: ", multiplication(a));
That is not how to print the result by calling the method.
I have taken your example and run the below code. You can check this code.
import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Enter the number: ");
int a = scan.nextInt();
int product = multiplication(a);
System.out.println("The result is : " +product);
}
public static int multiplication(int a){
int multiply = 0;
if(a == 5){
multiply = 10 * 6 * 2;
}else if(a == 4){
multiply = 6 * 2;
}else if(a == 1){
multiply = 2;
}
return multiply;
}
}
Below are the outputs on different options :
Enter the number: 4
The result is : 12
Enter the number: 5
The result is : 120
Enter the number: 1
The result is : 2

Stack Overflow on Random Integers

Where the commented section is, it says that there is a StackOverflowError - null. I am trying to get it to make random numbers to match up with an inputted value. The goal of this code is to do the following:
Accept a top number (ie 1000 in order to have a scale of (1-1000)).
Accept an input as the number for the computer to guess.
Computer randomly guesses the first number and checks to see if it is correct.
If it is not correct, it should go through a loop and randomly guess numbers, adding them to an ArrayList, until it guesses the input. It should check to see if the guess is already in the array and will generate another random number until it makes one that isn't in the list.
In the end, it will print out the amount of iterations with the count variable.
Code:
import java.util.*;
public class ArrNumGuess
{
public static Integer top, input, guess, count;
public static ArrayList <Integer> nums;
public static void main ()
{
System.out.println("Please enter the top number");
top = (new Scanner(System.in)).nextInt();
System.out.println("Please enter the number to guess (1 - " + top + ")");
input = Integer.parseInt(((new Scanner(System.in)).nextLine()).trim());
nums = new ArrayList<Integer>(); //use nums.contains(guess);
guess = (new Random()).nextInt(top) + 1;
nums.add(guess);
System.out.println("My first guess is " + guess);
count = 1;
if(guess != input)
{
guesser();
}
System.out.println("It took me " + count + " tries to find " + guess + " and " + input);
}
public static void guesser()
{
boolean check = false;
while(!check)
{
guess = (new Random()).nextInt(top) + 1; //Stack Overflow - null
if(nums.contains(guess) && !(guess.equals(input)))
{
count--;
guesser();
}
else if(guess.equals(input))
{
check = true;
System.out.println("My guess was " + guess);
// nums.add(guess);
count++;
}
else
{
System.out.println("My guess was " + guess);
nums.add(guess);
count++;
}
}
}
}
In guesser() method, you're invoking itself:
if(nums.contains(guess) && !(guess.equals(input)))
{
count--;
guesser();
}
There is quite a possibility it will never end. But all that is in while loop, so why not get rid of recurrence and do this in an iterative style?
OK - a different approach to your guesser for fun. Enumerate a randomized sequence of numbers in specified range (1 to 'top') and find the guess in the list whose index is effectively the number of "attempts" and return.
(BTW - #Andronicus answer is the correct one.)
/** Pass in 'guess' to find and 'top' limit of numbers and return number of guesses. */
public static int guesser(int guess, int top) {
List<Integer> myNums;
Collections.shuffle((myNums = IntStream.rangeClosed(1, top).boxed().collect(Collectors.toList())), new Random(System.currentTimeMillis()));
return myNums.indexOf(guess);
}
You are making it more complicated than it needs to be and introducing recursion unnecessarily. The recursion is the source of your stack overflow as it gets too deep before it "guesses" correctly.
There is a lot of sloppiness in there as well. Here's a cleaned up version:
import java.util.*;
public class Guess {
public static void main(String args[]) {
System.out.println("Please enter the top number");
Scanner scanner = new Scanner(System.in);
int top = scanner.nextInt();
System.out.println("Please enter the number to guess (1 - " + top + ")");
int input = scanner.nextInt();
if (input < 1 || input > top) {
System.out.println("That's not in range. Aborting.");
return;
}
ArrayList <Integer> nums = new ArrayList<>();
Random rng = new Random(System.currentTimeMillis());
while(true) {
int guess = rng.nextInt(top) + 1;
if (!nums.contains(guess)) {
nums.add(guess);
if (nums.size() == 1) {
System.out.println("My first guess is " + guess);
} else {
System.out.println("My guess was " + guess);
}
if (guess == input) {
System.out.println("It took me " + nums.size() + " tries to find " + guess);
break;
}
}
}
}
}

how to rewrite while to Do while in java

i have rewritten this in a do while loop but how can i make the division part retun/accept just three decimal place for example is if i get 1/4 i should be able to enter 0.25 and also if i get 1/7 i should be able to get 0.14.
import java.util.*;
public class HelloWorld
{
public static void main (String[] args)
{
Scanner keyboard=new Scanner(System.in);
Random quest=new Random();
int module,range,number,count,quest1,quest2,answer,score;
double result;
System.out.print("Enter module(1 for addition, 2 for subtraction, 3 for multiplication, 4 for division, -1 for exit)?");
module=keyboard.nextInt();
do{
System.out.print("Enter range of numbers(1-100)");
range=keyboard.nextInt();
System.out.print("How many questions do you want to practice(minimum 3)?");
number=keyboard.nextInt();
count=1;
score=0;
result=0;
while (count<= number)
{
quest1=quest.nextInt(range)+1;
quest2=quest.nextInt(range)+1;
if (module==1)
{
result=quest1+quest2;
System.out.print(quest1+"+" +quest2+"=");
}
else
{
if (module==2)
{
result=quest1-quest2;
System.out.print(quest1+"-" +quest2+"=");
}
else
{
if (module==3)
{
result=quest1*quest2;
System.out.print(quest1+"*" +quest2+"=");
}
else
{
if (module==4)
{
result=(double)quest1/quest2;
System.out.print(quest1+"/" +quest2+"=");
}
}
}
}
answer=keyboard.nextInt();
if(answer==result)
{
score=score+1;
System.out.println("you are correct!");
}
else {
System.out.println("You are wrong, the correct answer is " +result);
}
count=count+1;
if(count>number)
{
System.out.println("you scored "+score+" out of "+number+".");
count=1;
score=0;
break;
}
}
System.out.print("Enter module(1 for addition, 2 for subtraction, 3 for multiplication, 4 for division, -1 for exit)?");
module=keyboard.nextInt();
}while((module>0) && (module<5));
System.out.println("The program is terminating......");
}
}
Simple put whatever you have in the while loop, into a do - while loop like so:
do{
// Execute whatever
} while(conditionIsTrue);
Note that the difference between a while loop and a do while is that the do while loop executes 1 time always and then loops, where the while loop may not execute not even once because of the condition.
Personally I prefer tu use the while loop.

Explaining about prints output ordering of recursive loop?

Can anyone please explain the print order of the recursive loop?
import java.util.Scanner;
public class DecimalToBinary {
static Scanner console = new Scanner(System.in);
public static void main(String[] args) {
int decimalNum;
int base;
base = 2;
System.out.println("Enter a nonnegative integer in decimal: ");
decimalNum = console.nextInt();
System.out.println();
System.out.println("Decimal " + decimalNum + " = ");
decToBin(decimalNum, base);
System.out.println(" binary");
}
public static void decToBin(int num, int base) {
if (num == 0) {
System.out.print(0);
} else if (num > 0) {
decToBin(num / base, base);
System.out.print(num % base);
}
}
}
Num % base must print reverse order like this:
why is the order of calls as shown? (Please help me revise my question, English is my foreign language)
Your printing occurs after the recursion. Using (25, 2) as an example, the order of your calls with printing looks like
decToBin(25, 2):
decToBin(12,2):
decToBin(6,2):
decToBin(3,2):
decToBin(1,2):
decToBin(0,2):
print(0)
print(1%2)
print(3%2)
print(6%2)
print(12%2)
print(25%2)
Removing the recursive calls and just leaving the print statements shows the order you are getting:
decToBin(25, 2):
print(0)
print(1%2)
print(3%2)
print(6%2)
print(12%2)
print(25%2)
If you want the printing to be in the reverse order, move the print statement before the recursive call:
public static void decToBin(int num, int base) {
if (num == 0) {
System.out.print(0);
} else if (num > 0) {
System.out.print(num % base);
decToBin(num / base, base);
}
}
New recursion with printing:
decToBin(25, 2):
print(25%2)
decToBin(12,2):
print(12%2)
decToBin(6,2):
print(6%2)
decToBin(3,2):
print(3%2)
decToBin(1,2):
print(1%2)
decToBin(0,2):
print(0)
New output:
decToBin(25, 2):
print(25%2)
print(12%2)
print(6%2)
print(3%2)
print(1%2)
print(0)
the order of the output is reversed
because once the dectobin function is called
decToBin(int num, int base) {
if (num == 0) {
System.out.print(0);
} else if (num > 0) {
it reaches the line
decToBin(num / base, base);
where it postpones its execution and calls "another instance" of the dectobin function with decreased number parameter, before getting a chance to output anything(in the code below)
System.out.print(num % base);
}
then this subsequent call of dectobin is stopped at the same line and another "instance" is started with even smaller num. and so on and so on. none of the "instances" so far gets a chance to print anything.
at some point the "instance" of the function which was started last, recognizes that its
num argument has decreased under value of 1; and since num is integer type, once it is positive but less than 1 it is "Rounded" to 0. so that the following condition is true:
if (num == 0) {
System.out.print(0);
then this last instance behaves differently from all its predecessors. instead of postponing its execution and creating a new "instance" it prints '0' in the line above and just ends returning the execution point to the one "instance" which called it, which then continues to run from the line it was postponed.
then this "instance" outputs its number
system.out.print(num % base);
and ends itself returning the execution to the one which was starting it. and so and so on.
the bottom line is: the function "instance" which started last had the first output.the one which started first had the last

Categories

Resources