Recursion Troubling me - java

I'm new to all this so.. thanks
Just curious why this won't work.
Its telling me that public int sumFirst(int n) is an illegal start to an expression.
package program8;
public class Program8 {
public static void main(String[] args) {
public int sumFirst(int n)
{
Scanner input = new Scanner(System.in);
n = input.nextInt();
if (n == 0)
return 0;
else
return sumFirst(n-1) + sumFirst(n-2);
}
}

For one, you are trying to define a method inside your main method which will not work; Methods can only be defined at a class level.
Secondly, n = input.nextInt(); inside the sumFirst method will be executed for each recursion, which is probably not what you want.
Try this instead:
public class Program8 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println(sumFirst(input.nextInt()));
}
public int sumFirst(int n) {
if (n == 0) {
return 0;
} else {
return sumFirst(n-1) + sumFirst(n-2);
}
}
}

Related

How to get a specific type of exception in Java

I am trying to get a specific exception
Input
H=-1;
B=2;
Expected Output
java.lang.Exception: Breadth and height must be positive
Current Output
-2
public class Solution {
static int H,B;
static boolean flag = true;
static //static initializer block
{
Scanner sc = new Scanner(System.in);
H=sc.nextInt();
B=sc.nextInt();
}
public static void main(String[] args){
if(flag){
int area=B*H;
System.out.print(area);
}
}
}
How do I get that specific exception?
You can throw your own exception like this
if(H<0 || B<0){
throw new Exception("Breadth and height must be positive");
}
However, it would be a better practice to use something like a IllegalArgumentException for this.
if(H<0 || B<0){
throw new IllegalArgumentException("Breadth and height must be positive");
}
Add this as the first lines of your main method:
if(B < 1 || H < 1) {
throw new Exception("Breadth and height must be positive");
}
Add a throw statement. You can add it into a try catch block or instead add throws Exception (or a more specific exception) to the method signature (the latter is shown below):
import java.util.Scanner;
public class Solution {
static int H,B;
static boolean flag = true;
//static initializer block
static {
Scanner sc = new Scanner(System.in);
H = sc.nextInt();
B = sc.nextInt();
}
public static void main(String[] args) throws Exception {
if (flag) {
if (H < 0 || B < 0) {
throw new Exception("Breadth and height must be positive");
} else {
int area = B * H;
System.out.print(area);
}
}
}
}
Or you could put the try block with throw statement in your static initializer block:
import java.util.Scanner;
public class Solution {
static int H,B;
static boolean flag = true;
//static initializer block
static {
Scanner sc = new Scanner(System.in);
H = sc.nextInt();
B = sc.nextInt();
if (H < 0 || B < 0) {
try {
throw new Exception("Breadth and height must be positive");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
if (flag) {
int area = B * H;
System.out.print(area);
}
}
}

Setting up a global variable to count recursions

public class collatzpow {
public static int collatz(int n) {
StdOut.print( n + " ");
if (n == 1) return 0;
if (n% 2 == 0) return collatz(n/2);
else return collatz(3*n + 1);
}
public static void main(String[] args) {
int n= Integer.parseInt(args[0]);
StdOut.println(collatz(7));
}
}
I want to set up a global variable to count the number of time the program calls the recursion. I know with the number 7 it calls it 17 times.
I've been told it is very easy, but I'm struggling a bit with it.
Just declare a static int variable in the class scope and increment each time the method is called.
public class collatzpow {
public static int count = 0;
public static PrintStream StdOut = System.out;
public static int collatz(int n) {
++count;
StdOut.print(n + " ");
if (n == 1) return 0;
if (n % 2 == 0) return collatz(n / 2);
else return collatz(3 * n + 1);
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
StdOut.println(collatz(7));
System.out.println(count);
}
}

Method is illegal start of expression

Below is some code that tries to find the first word above a certain amount of characters.
public class FirstMatch {
public static void main(String[] args) throws java.io.FileNotFoundException {
Scanner in = new Scanner(new FileReader("aliceInWonderland.txt"));
String longWord = "";
boolean found = false;
public void threshold (int Threshold) {
while (in.hasNext() && !found) {
String word = in.next();
if (word.length() > Threshold) {
longWord = word;
found = true;
}
}
System.out.println("The first long word is: " + longWord);
}
}
}
(In the above code I didn't copy in all the import statements)
For some reason for my threshold method it returns illegal start of expression. I think it is a stupid mistake but can't figure out what's wrong...
You should declare your threshold method out of the main method.
A method can only be created at class level, and not inside another method.
import java.io.FileReader;
import java.util.Scanner;
public class FirstMatch {
public static void main(String[] args) throws java.io.FileNotFoundException {
Scanner in = new Scanner(new FileReader("aliceInWonderland.txt"));
threshold(in, 10);
}
public static void threshold(Scanner in, int threshold) {
String longWord = "";
boolean found = false;
while (in.hasNext() && !found) {
String word = in.next();
if (word.length() > threshold) {
longWord = word;
found = true;
}
}
System.out.println("The first long word is: " + longWord);
}
}

StackOverFlowError in java program [duplicate]

This question already has answers here:
What is a StackOverflowError?
(16 answers)
Closed 7 years ago.
I am trying to solve a problem which asks to find the smallest prime palindrome, which comes after a given number which means that if the input is 24, the output would be 101 as it is the smallest number after 24 which is both prime and a palindrome.
Now my code works perfectly for small values but the moment I plug in something like 543212 as input, I end up with a StackOverFlowError on line 20, followed by multiple instances of StackOverFlowErrors on line 24. Here is my code :
package nisarg;
import java.util.Scanner;
public class Chef_prime_palindromes {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
long num = input.nextLong();
isPalindrome(num + 1);
}
public static boolean isPrime(long num) {
long i;
for (i = 2; i < num; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
public static void isPalindrome(long num) {
String word = Long.toString(num);
int i;
for (i = 0; i < word.length() / 2; i++) {
if (word.charAt(i) != word.charAt(word.length() - i - 1)) {
isPalindrome(num + 1);
}
}
if (i == word.length() / 2) {
if (isPrime(num)) {
System.out.println(num);
System.exit(0);
} else {
isPalindrome(num + 1);
}
}
}
}
All shown exiting solutions use recursion and have the problem that at some point they will reach the point where a StackOverflowException will occur.
A better solution which would also be parallelizable would be to change it into a loop.
It could be something like:
package nisarg;
import java.math.BigInteger;
import java.util.Scanner;
import java.util.concurrent.CopyOnWriteArrayList;
public class Chef_prime_palindromes {
private static final CopyOnWriteArrayList<BigInteger> PRIMESCACHE
= new CopyOnWriteArrayList<>();
public static void main(String[] args) {
try (Scanner input = new Scanner(System.in)) {
BigInteger num = new BigInteger(input.nextLine());
initPrimes(num);
for (num = num.add(BigInteger.ONE);
!isPrimePalindrome(num);
num = num.add(BigInteger.ONE));
System.out.println(num.toString());
}
}
private static void initPrimes(BigInteger upTo) {
BigInteger i;
for (i = new BigInteger("2"); i.compareTo(upTo) <= 0 ; i = i.add(BigInteger.ONE)) {
isPrime(i);
}
}
public static boolean isPrimePalindrome(BigInteger num) {
return isPrime(num) && isPalindrome(num);
}
// could be optimized
public static boolean isPrime(BigInteger num) {
for (int idx = PRIMESCACHE.size() - 1; idx >= 0; --idx) {
if (num.mod(PRIMESCACHE.get(idx)).compareTo(BigInteger.ZERO) == 0) {
return false;
}
}
if (!PRIMESCACHE.contains(num)) {
PRIMESCACHE.add(num);
}
return true;
}
public static boolean isPalindrome(BigInteger num) {
String word = num.toString();
int i;
for (i = 0; i < word.length() / 2; i++) {
if (word.charAt(i) != word.charAt(word.length() - i - 1)) {
return false;
}
}
return true;
}
}
A new String object is created in each recursive call and placed onto stack (the place where all variables created in methods are stored until you leave the method), which for a deep enough recursion makes JVM reach the end of allocated stack space.
I changed the locality of the String object by placing it into a separate method, thus reducing its locality and bounding its creation and destruction (freeing of stack space) to one recursive call.
package com.company;
import java.util.Scanner;
public class Chef_prime_palindromes {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
long num = input.nextLong();
isPalindrom(num + 1);
}
public static boolean isPrime(long num) {
long i;
for (i = 2; i < num; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
private static void isPalindrom(long num) {
for (; ; ) {
if (isPalindrome(num)) {
if (isPrime(num)) {
System.out.println(num);
System.exit(0);
} else {
num++;
}
} else {
num++;
}
}
}
public static boolean isPalindrome(long num) {
String string = String.valueOf(num);
return string.equals(new StringBuilder(string).reverse().toString());
}
}
First thing you should be aware of is the fact that your resources are limited. Even if your implementation was precise and all recursive calls were correct, you may still get the error. The error indicates your JVM stack ran out of space. Try to increase the size of your JVM stack ( see here for details).
Another important thing is to look for the distribution of prime and palindrome numbers. Your code runs by testing every num+1 against palindrome property. This is incorrect. You test for palindrome only when the number is prime. This will make the computation much much easier (and reduce recursive calls). I have edited your code accordingly and got the closest palindrome number after 543212 (1003001) . Here it is:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
long num = input.nextLong();
//isPalindrome(num+1);
nextPrimePalindrome(num+1);
}
public static void nextPrimePalindrome(long num)
{
boolean flag=true;
while(flag)
{
if(isPrime(num))
if(isPalindrome(num))
{
System.out.println(num);
flag=false;
}
num++;
}
}
public static boolean isPrime(long num){
long i;
for(i=2;i<num;i++){
if(num%i == 0){
return false;
}
}
return true;
}
public static boolean isPalindrome(long num)
{
String word=Long.toString(num);
for(int i=0;i<word.length()/2;i++)
if(word.charAt(i)!=word.charAt(word.length()-i-1))
return false;
return true;
}
}

Java recursion to find prime factors doesn't work

I am trying to get all prime factors of a number. The for loop should work until it finds the match and it should break and jump to the next if statement which checks if number is not equal to zero.
public class Factor {
public static ArrayList <Integer> HoldNum = new ArrayList();
public static void main(String[]args){
Factor object = new Factor();
object.Factor(104);
System.out.println(HoldNum.get(0));
}
public static int Factor(int number){
int new_numb = 0;
int n=0;
for( n = 1; n < 9; n++) {
if (number % n == 0) {
HoldNum.add(n);
new_numb = number/n;
break;
}
}
System.out.println(new_numb);
if(new_numb < 0) {
HoldNum.add(new_numb);
return 1;
} else {
return Factor(new_numb);
}
}
}
There are at least three errors :
As okiharaherbst wrote, your counter is not incremented.
you start your loop at 1, so yourval % 1 always equals to 0 and new_numb is always equals to your input val, so you'll loop endlessly on 104.
new_numb will never be lesser than 0.
You asked for a recursive solution. Here you go:
public class Example {
public static void main(String[] args) {
System.out.println(factors(104));
}
public static List<Integer> factors(int number) {
return factors(number, new ArrayList<Integer>());
}
private static List<Integer> factors(int number, List<Integer> primes) {
for (int prim = 2; prim <= number; prim++) {
if (number % prim == 0) {
primes.add(prim);
return factors(number / prim, primes);
}
}
return primes;
}
}
The code is not bullet-proof, it is only a quick-and-dirty example.
Java implementation...
public class PrimeFactor {
public int divisor=2;
void printPrimeFactors(int num)
{
if(num == 1)
return;
if(num%divisor!=0)
{
while(num%divisor!=0)
++divisor;
}
if(num%divisor==0){
System.out.println(divisor);
printPrimeFactors(num/divisor);
}
}
public static void main(String[] args)
{
PrimeFactor obj = new PrimeFactor();
obj.printPrimeFactors(90);
}
}

Categories