Recursion in java, which one could be the best? - java

public class a1 {
private static int unit = 0;
private static int sum = 0;
public static void main(String[] foo) {
unit = 10;
System.out.println(tailRecur(unit));
System.out.println(tailRecur2(10));
}
public static int tailRecur(int result) {
int sum = result + unit - 1;
unit = unit - 1;
if (unit == 0) {
return sum;
}
return tailRecur(sum);
}
public static int tailRecur2(int unit) {
if (unit == 0) return sum;
sum = sum + unit;
return tailRecur2(unit - 1);
}
}
I wrote a simple method to get achieve 1+...+10. I am not sure which one could be better with the meaning of recursion syntax. The all give me the right answer.

Storing static variables is unnecessary, so either solution isn't ideal.
Try thinking like this
What are you trying to do? Answer: 1+...+N.
What is the input? Answer: N, the highest number to sum to.
What can you do in each step recursively that will help you reach your answer with that input? Answer: Take that number and add it to the result of all N - 1 solutions.
When should you stop recursion and start accumulating the summation results (what's your base case)? Answer: When the number hits 1 (generally, the smallest possible input), or even less than it to prevent a negative number input from causing a StackOverflow error.
public static int sumUpTo(int x) {
if (x <= 1) return x;
return x + sumUpTo(x - 1);
}

Related

How to prevent a recursive method from changing a value of a variable?

I'm learning Java, and I'm stuck on a recursion problem.
I need to use a recursive method to check if a number is an Armstrong number or not.
My code:
public class ArmstrongChecker {
public boolean isArmstrong(int number) {
// check if the number is a negative number
if (number < 0) {
return false;
}
ArmstrongChecker armstrongChecker = new ArmstrongChecker();
// find the length of the number
int length = armstrongChecker.lengthChecker(number);
// create a variable to store the sum of the digits of the number
int sum = 0;
// find the individual digits and raise to the power of the numbers of digits
if (number != 0) {
int digit = Math.floorMod(number, 10);
int powerRaised = (int) Math.pow(digit, length);
sum = sum + powerRaised;
isArmstrong(number / 10);
}
return sum == number;
}
// method to check the length of the number
public int lengthChecker(int number) {
int length = String.valueOf(number).length();
return length;
}
}
How do I prevent int length in isArmstrong() method from changing its value.
While you are not changing it's value in the posted code, you could mark that variable to be a constant. This way the compiler can error out if you tried to assign a new value.
final int length = armstrongChecker.lengthChecker(number);
As I've already said in the comments, your solution has the following issues:
The result of the recursive call isArmstrong() is being ignored;
There's no need for spawning new instances of ArmstrongChecker. And this method doesn't require object creation at all, it can be implemented as static.
Checking if the number is an Armstrong number boils down to calculating its Armstrong sum, the solution will be cleaner if you implement only this part using recursion.
It might look like this:
public static boolean isArmstrong(int number) {
if (number < 0) return false;
if (number < 10) return true;
return number == getArmstrongSum(number, String.valueOf(number).length());
}
public static int getArmstrongSum(int number, int power) {
if (number == 0) {
return 0;
}
return (int) Math.pow(number % 10, power) + getArmstrongSum(number / 10, power);
}
main()
public static void main(String[] args) {
System.out.println(isArmstrong(370)); // true
System.out.println(isArmstrong(12)); // false
System.out.println(isArmstrong(54)); // false
System.out.println(isArmstrong(153)); // true
}
Output:
true
false
false
true
You need to get the length once for whole recursion, so the cleanest approach would be to pass down both the number and the length into the recursion. An easy way to do this is to have one method that is the public face of the API, and another that does the recursion.
public class ArmstrongChecker {
public boolean isArmstrong(int number) {
if (number < 0) {
return false;
}
int length = lengthChecker(number);
int sum = armstrongSum(number, length);
return sum == number;
}
private int armstrongSum(int number, int length) {
int sum = 0;
if (number != 0) {
int digit = Math.floorMod(number, 10);
int powerRaised = (int) Math.pow(digit, length);
sum += powerRaised;
sum += armstrongSum(number / 10, length);
}
return sum;
}
public int lengthChecker(int number) {
int length = String.valueOf(number).length();
return length;
}
}
This is pretty common in recursion, where the parameters to the recursive part of the algorithm are a little different (usually there are more of them) than what you want a client of the API to have to pass in. The number changes in each recursive call, where number / 10 is passed down, but the same length is passed all the way through.
Notice that the recursive armstrongSum uses the return value from the recursive call, and that there is no need to create another instance of ArmstrongChecker when you are already in an instance method of the class.

TestDome: my solution works but I am only getting %50 right and not %100?

This is the scenario question:
A frog only moves forward, but it can move in steps 1 inch long or in jumps 2 inches long. A frog can cover the same distance using different combinations of steps and jumps.
Write a function that calculates the number of different combinations a frog can use to cover a given distance.
For example, a distance of 3 inches can be covered in three ways: step-step-step, step-jump, and jump-step.
public class Frog{
public static int numberOfWays(int input) {
int counter = 2;
int x = 0;
for (int i = 1 ; i< input -1; i++ ){
x = i + counter;
counter = x;
}
if (input <3){
x = input;
}
return x;
}
public static void main(String[] args) {
System.out.println(numberOfWays(10));
}
}
This solution only gives me %50 right not sure why its not %100 right, I tested it with other values and returns the right results.
I think recursion is a nice way to solve problems like that
public int numberOfCombinations(int distance) {
if (distance == 1) {
return 1; //step
} else if (distance == 2) {
return 2; // (step + step) or jump
} else {
return numberOfCombinations(distance - 1) + numberOfCombinations(distance - 2);
// we jumped or stepped into the current field
}
}
Let f[n] be the number of combinations of steps and jumps such that you travel n inches. You can immediately see that f[n] = f[n-1] + f[n-2], that is first you can travel n-1 inches in some way and then use 1 step or you can travel n-2 inches in some way and then use 1 jump. Since f[1] = 1 and f[2] = 2 you can see that f[n] = fib(n+1), the n+1-th Fibonacci number. You can calculate it in linear time if it suits the purpose or, more efficiently, you can calculate it in log n time - reference
The problem is a modified version of the Fibonacci series. I get 100% for the following (sorry it's C# but is very similar):
using System;
public class Frog
{
public static int NumberOfWays(int n)
{
int firstnumber = 0, secondnumber = 1, result = 0;
if (n == 1) return 1;
if (n == 2) return 2;
for (int i = 2; i <= n + 1; i++)
{
result = firstnumber + secondnumber;
firstnumber = secondnumber;
secondnumber = result;
}
return result;
}
public static void Main(String[] args)
{
Console.WriteLine(NumberOfWays(3));
Console.WriteLine(NumberOfWays(4));
Console.WriteLine(NumberOfWays(5));
Console.WriteLine(NumberOfWays(6));
Console.WriteLine(NumberOfWays(7));
Console.WriteLine(NumberOfWays(8));
}
}
Think overlapping subproblem / dynamic programming. You need to memorize the repetitive calls to the sub-problem which will save you all the time.
I believe this should cover your all scenarios.
public static string numberOfCombinations(int distance)
{
if (distance == 1) {
return "Step";//1
} else if (distance == 2) {
return "Jump";//2
} else{
return numberOfCombinations(1) + numberOfCombinations(distance - 1);
}
}

Method to find the smallest number from an integer

So I need to develop a method to find the smallest digit in an integer.
Here is my implementation
public int find(int n){
if(n < 10) return n;
return Math.min(n%10, find(n/10));
}
You can change the int by long ...
If you're interested in learning how to figure this out yourself (and you should be), I would try following these steps.
Do the process in your head, slowly - or even better, write the steps on paper! Take notice of each step you take.
Step one may be: look at the first digit
Consider the steps you've created. Are there parts which seem to be repeating themselves? These parts will likely be your recursive function.
Rewrite the steps as a recursive function (in plain English)
Translate the steps into your programming language; Java, in this case.
If you want, you can even leave the plain english steps in your code behind each line as comments, so everyone can easily follow your code
Personally I think a for loop would be quicker and easier than a recursive function. But for recursion or a for loop you need something to iterate on. Easiest way is to convert the number to a string and then iterate through it doing needed comparisons.
In your main:
int i = 578329;
String s = Integer.toString(i);
s = FindSmallest(s);
Call the function:
private String FindSmallest(String s){
if(s.length() <= 1)
return s;
String sFirstChar = s.substring(0,1);
String sSecondChar = s.substring(1,2);
int iFirst = Integer.parseInt(sFirstChar);
int iSecond = Integer.parseInt(sSecondChar);
if(iFirst < iSecond)
return FindSmallest( sFirstChar + s.substring(2));
else
return FindSmallest(sSecondChar + s.substring(2));
}
public static int find(int num) {
if(num < 10){
return num;
}
int d = num % 10;
int pmin = find(num / 10);
return (d <= pmin) ? d : pmin;
}
You can also write:
public static int minDigit(int n, int min){
if(n!=0) {
if(n%10 < min) {
min = n%10;
}
return minDigit(n/10, min);
}
return min;
}

Memoization with recursive method in java

I am working on a homework assignment, and I have completely exhausted myself. I'm new to programming, and this is my first programming class.
this is the problem:
Consider the following recursive function in Collatz.java, which is related to a famous unsolved problem in number theory, known as the Collatz problem or the 3n + 1 problem.
public static void collatz(int n) {
StdOut.print(n + " ");
if (n == 1) return;
if (n % 2 == 0) collatz(n / 2);
else collatz(3*n + 1);}
For example, a call to collatz(7) prints the sequence
7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
as a consequence of 17 recursive calls. Write a program that takes a command-line argument N and returns the value of n < N for which the number of recursive calls for collatz(n) is maximized. Hint: use memoization. The unsolved problem is that no one knows whether the function terminates for all positive values of n (mathematical induction is no help because one of the recursive calls is for a larger value of the argument).
I have tried several things: using a for loop, trying to count the number of executions with a variable incremented each time the method executed, and hours of drudgery.
Apparently, I'm supposed to use an array somehow with the memoization. However, I don't understand how I could use an array when an array's length must be specified upon initiation.
Am I doing something completely wrong? Am I misreading the question?
Here is my code so far. It reflects an attempt at trying to create an integer array:
public class Collatz2 {
public static int collatz2(int n)
{
StdOut.print(n + " ");
if (n==1) {return 1;}
else if (n==2) {return 1;}
else if (n%2==0) {return collatz2(n/2);}
else {return collatz2(3*n+1);}
}
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]);
StdOut.println(collatz2(N));
}
}
EDIT:
I wrote a separate program
public class Count {
public static void main(String[] args) {
int count = 0;
while (!StdIn.isEmpty()) {
int value = StdIn.readInt();
count++;
}
StdOut.println("count is " + count);
}
}
I then used piping: %java Collatz2 6 | java Count
and it worked just fine.
Since you are interested in the maximum sequence size and not necessarily the sequence itself, it is better to have collatz return the size of the sequence.
private static final Map<Integer,Integer> previousResults = new HashMap<>();
private static int collatz(int n) {
int result = 1;
if(previousResults.containsKey(n)) {
return previousResults.get(n);
} else {
if(n==1) result = 1;
else if(n%2==0) result += collatz(n/2);
else result += collatz(3*n + 1);
previousResults.put(n, result);
return result;
}
}
The memoization is implemented by storing sequence sizes for previous values of n in Map previousResults.
You can look for the maximum in the main function:
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
int maxn=0, maxSize=0;
for(int n=N; n>0; n--) {
int size = collatz(n);
if(size>maxSize) {
maxn = n;
maxSize = size;
}
}
System.out.println(maxn + " - " + maxSize);
}
The trick here is to write a recursive method where an argument is the value you want to "memoize". For instance, here is a version of a method which will return the number of steps needed to reach 1 (it supposes that n is greater than or equal to 1, of course):
public int countSteps(final int n)
{
return doCollatz(0, n);
}
public static int doCollatz(final int nrSteps, final int n)
{
if (n == 1)
return nrSteps;
final int next = n % 2 == 0 ? n / 2 : 3 * n + 1;
return doCollatz(nrSteps + 1, next);
}
If you were to record the different steps instead, you'd pass a List<Integer> as an argument and .add() to it as you went through, etc etc.

How to write a function that can calculate power in Java. No loops

I've been trying to write a simple function in Java that can calculate a number to the nth power without using loops.
I then found the Math.pow(a, b) class... or method still can't distinguish the two am not so good with theory. So i wrote this..
public static void main(String[] args) {
int a = 2;
int b = 31;
System.out.println(Math.pow(a, b));
}
Then i wanted to make my own Math.pow without using loops i wanted it to look more simple than loops, like using some type of Repeat I made a lot of research till i came across the commons-lang3 package i tried using StringUtils.repeat
So far I think this is the Syntax:-
public static String repeat(String str, int repeat)
StringUtils.repeat("ab", 2);
The problem i've been facing the past 24hrs or more is that StringUtils.repeat(String str, int 2); repeats strings not out puts or numbers or calculations.
Is there anything i can do to overcome this or is there any other better approach to creating a function that calculates powers?
without using loops or Math.pow
This might be funny but it took me while to figure out that StringUtils.repeat only repeats strings this is how i tried to overcome it. incase it helps
public static int repeat(int cal, int repeat){
cal = 2+2;
int result = StringUtils.repeat(cal,2);
return result;
}
can i not use recursion maybe some thing like this
public static RepeatThis(String a)
{
System.out.println(a);
RepeatThis(a);
}
just trying to understand java in dept thanks for all your comments even if there were syntax errors as long as the logic was understood that was good for me :)
Another implementation with O(Log(n)) complexity
public static long pow(long base, long exp){
if(exp ==0){
return 1;
}
if(exp ==1){
return base;
}
if(exp % 2 == 0){
long half = pow(base, exp/2);
return half * half;
}else{
long half = pow(base, (exp -1)/2);
return base * half * half;
}
}
Try with recursion:
int pow(int base, int power){
if(power == 0) return 1;
return base * pow(base, --power);
}
Function to handle +/- exponents with O(log(n)) complexity.
double power(double x, int n){
if(n==0)
return 1;
if(n<0){
x = 1.0/x;
n = -n;
}
double ret = power(x,n/2);
ret = ret * ret;
if(n%2!=0)
ret = ret * x;
return ret;
}
This one handles negative exponential:
public static double pow(double base, int e) {
int inc;
if(e <= 0) {
base = 1.0 / base;
inc = 1;
}
else {
inc = -1;
}
return doPow(base, e, inc);
}
private static double doPow(double base, int e, int inc) {
if(e == 0) {
return 1;
}
return base * doPow(base, e + inc, inc);
}
I think in Production recursion just does not provide high end performance.
double power(double num, int exponent)
{
double value=1;
int Originalexpn=exponent;
double OriginalNumber=num;
if(exponent==0)
return value;
if(exponent<0)
{
num=1/num;
exponent=abs(exponent);
}
while(exponent>0)
{
value*=num;
--exponent;
}
cout << OriginalNumber << " Raised to " << Originalexpn << " is " << value << endl;
return value;
}
Use this code.
public int mypow(int a, int e){
if(e == 1) return a;
return a * mypow(a,e-1);
}
Sure, create your own recursive function:
public static int repeat(int base, int exp) {
if (exp == 1) {
return base;
}
return base * repeat(base, exp - 1);
}
Math.pow(a, b)
Math is the class, pow is the method, a and b are the parameters.
Here is a O(log(n)) code that calculates the power of a number. Algorithmic technique used is divide and conquer. It also accepts negative powers i.e., x^(-y)
import java.util.Scanner;
public class PowerOfANumber{
public static void main(String args[]){
float result=0, base;
int power;
PowerOfANumber calcPower = new PowerOfANumber();
/* Get the user input for the base and power */
Scanner input = new Scanner(System.in);
System.out.println("Enter the base");
base=input.nextFloat();
System.out.println("Enter the power");
power=input.nextInt();
result = calcPower.calculatePower(base,power);
System.out.println(base + "^" + power + " is " +result);
}
private float calculatePower(float x, int y){
float temporary;
/* Termination condition for recursion */
if(y==0)
return 1;
temporary=calculatePower(x,y/2);
/* Check if the power is even */
if(y%2==0)
return (temporary * temporary);
else{
if(y>0)
return (x * temporary * temporary);
else
return (temporary*temporary)/x;
}
}
}
Remembering the definition of the logarithm, this can be done with ln and exp if these functions are allowed. Works for any positive base and any real exponent (not necessarily integer):
x = 6.7^4.4
ln(x) = 4.4 * ln(6.7) = about 8.36
x = exp(8.36) = about 4312.5
You can read more here and also here. Java provides both ln and exp.
A recursive method would be the easiest for this :
int power(int base, int exp) {
if (exp != 1) {
return (base * power(base, exp - 1));
} else {
return base;
}
}
where base is the number and exp is the exponenet

Categories

Resources