More elegant inner methods declarations (without all the clutter)? - java

I have a recursive method that computes x^n with a certain algorithm, but this is of no importance here. What matters is my helper function which keeps track of recursive calls of this algorithm.
public class FastPot {
public static double fastPotRek(double x, int n) {
class Aux {
private double aux(double x, int n, int c) {
if (n == 0) {System.out.print("It took "+c+" recursive calls to compute "); return 1;}
else return (n % 2 == 0) ? aux(x*x, n/2, c+1)
: x * aux(x, n-1, c+1);
}
}
Aux a = new Aux();
return a.aux(x, n, 0);
}
}
To organize that somewhat I wanted to declare aux inside fastPotRek, and for that you have to use an inner class, whose methods I can't declare static. Because of this I instantiate Aux a = new Aux(); to be able to call aux.
Please tell me there is a way to make this more elegant and show me what I have overlooked... Like beeing able to make aux static somehow or not needing to instantiate Aux.

No need for inner class and no need to make that static as well:
public class FastPot {
//Static, use only from within FastPot
private static double aux(double x, int n, int c) {
if (n == 0) {
System.out.print("It took "+c+" recursive calls to compute ");
return 1;
} else {
return (n % 2 == 0) ? aux(x*x, n/2, c+1)
: x * aux(x, n-1, c+1);
}
}
}
//Your outward interface
public static double fastPotRek(double x, int n) {
return aux(x, n, 0);
}
}
Or if you insist on using an inner class:
public class FastPot {
//Static, use only from within FastPot
private static class Aux {
private static double aux(double x, int n, int c) {
if (n == 0) {
System.out.print("It took "+c+" recursive calls to compute ");
return 1;
} else {
return (n % 2 == 0) ? aux(x*x, n/2, c+1)
: x * aux(x, n-1, c+1);
}
}
}
//Your outward interface
public static double fastPotRek(double x, int n) {
return Aux.aux(x, n, 0);
}
}

I'll post this answer although many people (including me) will not be happy with this. Please don't use this kind of code:
public static double fastPotRek(double x, int n) {
return new Cloneable() {
private double aux(double x, int n, int c) {
if (n == 0) {System.out.print("It took "+c+" recursive calls to compute "); return 1;}
else return (n % 2 == 0) ? aux(x*x, n/2, c+1) : x * aux(x, n-1, c+1);
}
}.aux(x, n, 0);
}
Again, i highly suggest to use a private static method like:
public static double fastPotRek(double x, int n) {
return aux(x,n,0);
}
private static double aux(double x, int n, int c) {
...
}

You have this:
Aux a = new Aux();
return a.aux(x, n, 0);
I would write it like this (Does the same):
return new Aux().aux(x, n, 0);
Edit: I´m done with StackOverflow. You guys don´t want help? I won´t give it. From now on, I will only ask about MY problems, and won´t answer.

Related

Why does this code give a StackOverflowError

I'm writing a method which is calculating the formula (x+y)/z if every variable's value is greater than zero. If they're smaller than zero the console should print "0".
My code looks like this:
package arrayTest;
public class berechne {
public static int berechneZahlen (int x, int y, int z) { //method
int ergebnis=0;
if (berechneZahlen(x, y, z) > 0) {
ergebnis = (x+y)/z; //ergebnis = result
}
else {
System.out.println("0");
}
return ergebnis;
}
public static void main(String[] args) {
System.out.print(berechneZahlen(2, 3, 6));
}
}
Now, in the editor I don't get any error. Everything seems fine. But when I'm compiling it, it gives me this error a dozen times:
Exception in thread "main" java.lang.StackOverflowError
at arrayTest.berechne.berechneZahlen(berechne.java:7)
at arrayTest.berechne.berechneZahlen(berechne.java:7)
at arrayTest.berechne.berechneZahlen(berechne.java:7)
I couldn't figure it out why the code isn't working properly.
You're calling your function recursively without termination point, so it cause StackOverFlowError
if (berechneZahlen(x, y, z) > 0)
Instead, introduce your code to check for x, y, x > 0 to match your requirement:
if every variable's value is greater than zero. If they're smaller than zero the console should print "0".
if (x > 0 && y > 0 && z > 0) {
//bla bla
} else {
//print 0
}
The method calls itself recursively. Try this:
public static int berechneZahlen (int x, int y, int z) { //method
int ergebnis=0;
if (z>0 && (x+y) > 0) {
ergebnis = (x+y)/z; //ergebnis = result
}
else {
System.out.println("0");
}
return ergebnis;
}
there are a couple of things wrong but also some things that can be improved.
what causes the error is that you are not checking if x,y,z is bigger than 0 but you are checking if berechneZahlen of those numbers is bigger than 0 which causes it to be called recursivly.
Furthermore in the case of one of them being 0 you are printing "0" in the method but you are also printing the result of berechneZahlen in your main function, resulting in "0" being printed twice, so you probably only want to return 0 in that case and not print it in the function itself.
Finally, I would also remove your ergebnis variable. It's not wrong but it's not necessary. you could simply just return the result.
This would then be your final result
public static int berechneZahlen (int x, int y, int z) {
if (x > 0 && y > 0 && z > 0) {
return (x+y)/z;
} else {
return 0;
}
}
But it can even be made shorter using a ternary operation like this
public static int berechneZahlen (int x, int y, int z) {
return (x > 0 && y > 0 && z > 0) ? (x+y)/z : 0;
}
The StackoverflowError is caused by a recursive call. That means the method berechneZahlen() is calling itself. In that call it is calling itself again and in that next call it is calling itself again and so on..
public static int berechneZahlen (int x, int y, int z) {
...
if (berechneZahlen(x, y, z) > 0) { // (fatal) recursive call here
...
}
Each single call allocates space on your computers memory until the memory is completely filled up with data and there is no more space left. In this moment the program execution breaks down, because it needs to allocate more space to work, but it can't allocate more.
Here is a working solution for you, where the recursion has been removed:
public class berechne {
public static int berechneZahlen (int x, int y, int z) {
if (x < 0 || y < 0 || z < 0) {
return 0; // return 0, if one of the numbers is below zero
}
return (x+y)/z; // return normal calculated result
}
public static void main(String[] args) {
System.out.print(berechneZahlen(2, 3, 6));
}
}

How to get the goldenRatio using recursion in Java?

I'm working on this simple java recursion problem given the following directions:
Calculate the golden ratio.
Given two numbers a and b with a > b > 0, the ratio is b / a.
I have done some code but I'm stuck on getting the recursion working properly. Here's my code:
public class MyTesting {
public static void main(String[] args) {
System.out.println(ratio(8 , 4));
}
public static double ratio(int a, int b) {
int goldelRatio = 0;
if(a > b && b > 0){
return goldelRatio = a / b;
}
return goldelRatio;
}
}
How about something like this:
double goldenRatio(double a, double b, double epsilon) {
if(Math.abs((b / a) - ((a + b) / b)) < epsilon) {
return ((a + b) / b);
} else {
return goldenRatio(b, a + b, epsilon);
}
}
This way you achieve what you need in one function, with epsilon deciding how fine the resolution would be.
Also as an added bonus, and although Java doesn't have (at the time of writing this at least) tail recursion optimization, in theory this function could be optimized by tail recursion.
example with hard coded epsilon:
double goldenRatio(double a, double b) {
double epsilon = 0.00001;
if(Math.abs((b / a) - ((a + b) / b)) < epsilon) {
return ((a + b) / b);
} else {
return goldenRatio(b, a + b);
}
}
example run:
public static void main(String[] args) {
double goldenRation1 = goldenRatio(1.0, 1.0);
System.out.println(goldenRation1); // prints 1.618032786885246
System.out.println(goldenRation1 > 1.61800 && goldenRation1 < 1.61806); // prints true
double goldenRation2 = goldenRatio(100.0, 6.0);
System.out.println(goldenRation2); // prints 1.6180367504835589
System.out.println(goldenRation2 > 1.61800 && goldenRation2 < 1.61806); // prints true
}
Yours is not a recursive function, a recursive function that calculates Golden Ratio would look like the one below.
private int MAX_COUNTER = 50;
private int count = 0;
public double ratio(double a, double b) {
count++;
double goldenRatio = b / a;
if (count < MAX_COUNTER) {
return ratio(b, a + b);
}
return goldenRatio;
}
NOTE: I put the counters because given that is a recursive function trying to find a number with infinite decimals, it will cause the JVM to go on StackOverflow :) , so we got to stop it sooner or later.
Recursion mainly means methods calling themself, meaning you should try something like that:
public double recursionMethod(int a, int b){
int c = a+b;
if(Math.abs(ratio(b,a)-ratio(c,b))< (double) 1/42)
return ratio(c,b);
else
return recursionMethod(b,c);
}
1/42 is just your accuracy, you can implement any other breaking condition you like. Call this method in main with arguments (1,1).

e^x = 1 + x + x2/2! + x3/3! + x4/4! << e to the x power using java method

So. Hello smart ones. What am I doing wrong here? I just can't figure out what is wrong with this code. 10 points for whomever helps me.
I'm trying to use recursion to make a method for e^x. using the e^x = 1 + x + x2/2! + x3/3! + x4/4! + ... equation
public class tester {
public static double power(double x, int n) {
if (n == 0) {
return 1;
} else {
return x * power(x, n - 1);
}
}
public static int factorial(int n) {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
public static double myexp(double x, int n) {
if (n == 0) {
return 1;
} else {
return (power(x, n) / factorial(n)) + myexp(x, n - 1);
}
}
public static void main(String[] args) {
System.out.println(myexp(x, n)); // unfortunately, increasing n value
// makes it go infinite.
}
}
So x is the x in e^x and n is the total value when up to nth term is added. So
for example, myexp(3,5) is going to be e^3 added up to 5th term. Thus, the higher the n is, the more accurate e^3 is going to be.
Your problem is the use of the "int" data type for the factorial method. More specifically, factorial numbers quickly become huge and the int data type is too small. For example, if you code:
public static void main(String[] args) {
System.out.println(factorial(50));
}
The output is 0 which is obviously wrong, hence your result of Infinity. Simply change the return type of factorial from intto double as follows:
public static double factorial(int n)
And then if you try:
public static void main(String[] args) {
System.out.println(myexp(1., 100));
}
You get 2.7182818284590455

What does the method prod() do in this Java program?

public class Prod {
public static void main(String[] args) {
System.out.println(prod(1, 4));
}
public static int prod(int m, int n) {
if (m == n) {
return n;
} else {
int recurse = prod(m, n-1);
int result = n * recurse;
return result;
}
}
}
This is an exercise in the book I am stumped on. Why would the program not just recurse until the two numbers are equal and then return n ? Also, where it says,
int result = n * recurse;
How does it multiply int n by recurse which would be (int, int)? How can it multiply one integer by a set of two integers?
In what way am I misunderstanding this program?
EDIT: This is a different question because I am not using factorials
prod(x,y) is equivalent to y! when x=1.
If x is different from 1, then its doing recursive multiplication (y * (y- 1) * (y -2) .... ) until y = x.
Assuming y > x.
By the way, if x > y then prod() will crash.

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