I am beginner in programming and I was wondering how you can write lambda expressions with conditions.
public interface MathInterface {
public int retValue(int x);
}
public class k1{
public static void main(String [] args) {
MathInterface f1 = (int x) -> x + 4; // this is a normal lambda expression
}
}
The code above should represent the mathematical function:
f(x) = x + 4.
So my question is how can i write a lambda expression that covers this function:
f(x) =
x/2 (if x is divisble by 2)
((x + 1)/2) (otherwise)
any help appreciated :)
Edit: The answer from #T.J. Crowder was, what I was searching.
MathInteface f1 = (int x) -> (x % 2 == 0) ? x / 2 : (x + 1) / 2;
So my question is how can i write a lambda expression that covers this function...
You either write a lambda with a block body ({}) (what I call a "verbose lambda") and use return:
MathInteface f1 = (int x) -> {
if (x % 2 == 0) {
return x / 2;
}
return (x + 1) / 2;
};
or you use the conditional operator:
MathInteface f1 = (int x) -> (x % 2 == 0) ? x / 2 : (x + 1) / 2;
(or both).
More details in the lambda tutorial.
For that particular function, a ternary would be possible.
(int x) -> x % 2 == 0 ? x/2 : (x+1)/2;
Otherwise, make a block
(int x) -> {
// if... else
}
Inside of which, you return the value
This return an integer :
public static void main(String [] args) {
MathInterface f1 = (int x) -> (x%2 ==0) ? x/2 : ((x + 1)/2);
}
If you feel like being cheeky, you can actually exploit integer division here.
When you divide two integers, the part of the number after the decimal point is automatically dropped. So 5 / 2 = 2.
For that reason, you can get away with just the odd number case:
MathInterface f1 = (int x) -> (x + 1) / 2;
In the case of even numbers, when they are incremented they will become odd, resulting in a .5 which will be dropped automatically.
I wouldn't recommend this approach because it's not clear you (the original programmer) are aware what's going on. Being explicit is better.
Related
public static void main(String[] args) {
int n = factorial(30);
int x = 0;
while (x <= 30) {
System.out.println(x + " " + n);
x = x + 1;
}
public static int factorial (int n) {
if (n == 0) {
return 1;
} else {
return n * factorial (n-1);
}
}
}
I'm trying to print out something like this:
0 1
1 1
2 2
3 6
4 24
...etc, up to 30 (30!)
What I'm getting instead is this:
0 (30!)
1 (30!)
...etc, up to 30
In words, I'm able to create the left column from 0 to 30 but I want to make it print the factorial of the numbers in the right hand column. With my code, it only prints the factorial of 30 in the right-hand column. I want it to print the factorials in order next to their corresponding number. How can I fix my code to do this?
This is pretty simple. Instead of defining a variable, you call the method with the updated x every time:
System.out.println(x + " " + factorial(x));
Note that your loop could be rewritten as a for loop, which is exactly what they're designed for:
for (int x = 0; x < 30; x++) {
System.out.println(x + " " + factorial(x));
}
Note a couple of things:
The x++. It's basically a short form of x = x + 1, though there are some caveats. See this question for more information about that.
x is defined in the loop (for (int x = ...) not before it
n is never defined or used. Rather than setting a variable that's only used once, I directly used the result of factorial(x).
Note: I'm actually pretty certain that an int will overflow when confronted with 30!. 265252859812191058636308480000000 is a pretty big number. It also overflows long, as it turns out. If you want to handle it properly, use BigInteger:
public BigInteger factorial(int n) {
if (n == 0) {
return BigInteger.ONE;
} else {
return new BigInteger(n) * factorial(n - 1);
}
}
Because of BigInteger#toString()'s magic, you don't have to change anything in main to make this work, though I still recommend following the advice above.
As #QPaysTaxes explains, the issue in your code was due to computing the final value and then printing it repeatedly rather than printing each step.
However, even that working approach suffers from a lack of efficiency - the result for 1 computes the results for 0 and 1, the result for 2 computes the results for 0, 1, and 2, the result for 3 computes the results for 0, 1, 2, and 3, and so on. Instead, print each step within the function itself:
import java.math.BigInteger;
public class Main
{
public static BigInteger factorial (int n) {
if (n == 0) {
System.out.println("0 1");
return BigInteger.ONE;
} else {
BigInteger x = BigInteger.valueOf(n).multiply(factorial(n - 1));
System.out.println(n + " " + x);
return x;
}
}
public static void main(String[] args)
{
factorial(30);
}
}
Of course, it would be faster and simpler to just multiply in the loop:
import java.math.BigInteger;
public class Main
{
public static void main(String[] args)
{
System.out.println("0 1");
BigInteger y = BigInteger.ONE;
for (int x = 1; x < 30; ++x) {
y = y.multiply(BigInteger.valueOf(x));
System.out.println(x + " " + y);
}
}
}
Just for fun, here's the efficient recursive solution in Python:
def f(n):
if not n:
print(0, 1)
return 1
else:
a = n*f(n-1)
print(n, a)
return a
_ = f(30)
And, better still, the iterative solution in Python:
r = 1
for i in range(31):
r *= i or 1
print(i, r)
Here's the working recursive power function alternative to Math.Pow class:
public class Powers {
public static long pow(long x, long p) {
if (p == 0) {
return 1;
}
if (p % 2 == 0) {
long a = pow(x, (p / 2));
return a * a; //This line
} else {
long a = pow(x, ((p - 1) / 2));
return x * a * a; //This line
}
}
}
If I try to be clever and use as much recursion as possible by changing the lines mentioned above to return pow(a, 2) and return x * pow(a, 2), I get a stack overflow error. I get that it should cause considerably more calls to pow, but I don't think it should loop like it appears to. Can anyone explain me through this? Thanks
Doing this you will get the following sequence of calls:
pow(a, 2) -> pow(a, 1) -> pow(a, 0) -> pow(1, 2) -> pow(1, 1) -> pow(1, 0) -> pow(1, 2) -> ...
You should either debug this with some IDE, or simply add some expression in the beginning of the method:
public static long pow(long x, long p) {
System.out.println ("x = " + x + ", p = " + p);
...
Then, read the output, it will contain the sequence of calls of pow
The standard Ackermann formula as written in Java:
public static int ack(int x, int y) {
if (x == 0) {
return y + 1;
} else if (y == 0) {
return ack(x-1, 1);
} else {
// perforce (x > 0) && (y > 0)
return ack(x-1, ack(x,y-1));
}
}
I've been wondering - is there a faster version to implement this? I'm thinking maybe there is by using an accumulator or a loop.
Yes, for example by "cheating". If m is 5 or higher, none of the results can be represented by an int. For m = 4, only the n < 2 cases can be represented. For m < 4, there are simple closed formula's based on n.
Everything else would overflow anyway, so let's pretend those cases don't even happen (or you could throw an error or whatever).
Not tested:
int Ackerman(int m, int n) {
switch (m) {
case 0:
return n + 1;
case 1:
return n + 2;
case 2:
return n * 2 + 3;
case 3:
return (int)((1L << (n + 3)) - 3);
case 4:
return n == 0 ? 13 : 65533;
}
}
I can tell you one thing... int will not suffice for very many values of x and y
If you're going to be calling the function repetitively, you can create a int[][] array to store various values so you can look them up the second+ time around and only need to compute it once. But as for speeding up a single execution... not sure.
This variation is faster:
public static int ack(int x, int y) {
while (x != 0) {
y = y == 0 ? 1 : ack(x, y - 1);
x--;
}
return y + 1;
}
I have to make a multiplication function without the * or / operators. I have already made a method like this.
for(int i=0; i < number1; i++){
result += number2;
}
System.Out.println(result);
Now, here is my problem: It was fine until my lecturer change the topic, where the multiplication method must be can multiply decimal value. I had no idea how I can make multiplication method which can work on decimal value with just + and - operator.
yeah you can use log for the multiplication.
log(a*b)=log(a)+log(b)
and then find out the exponential value of log(a)+log(b)
and then you can convert the sign..
for example:
-9*8=-72
log(9*8)=log(9)+log(8)=2.19+2.07=4.27
e^4.27=72
now there is only one -ve no. then it is -72
else it's 72
I'm writing the function for:
void multiply(int num1,int num2)
{
int counter=0;
if(num1<0)
{counter++;num1+=num1+num1;}
if(num2<0)
{counter++;num2+=num2+num2;}
double res=Math.log(num1)+Math.log(num2);
int result=(int)Math.exp(res);
if(counter%2==0)
System.out.println("the result is:"+result);
else
System.out.println("the result is:-"+result);
}
hope this will help you....
You take the decimal numbers and move the decimal point step by step until there is an int left: 0.041 -> 1. step 0.41 -> 2. step 4.1 -> 3. step 41
multiplying 0.041 * 3 could be done by doing the above step 3 times, multiplying 41 * 3 = 123. For the result you take the 123 and undu the steps: 1. 12.3, 2. 1.23, 3. 0.123. There is your result: 0.123 = 0.041 * 3.
Edit:
To determine the number of decimals for each number, you might find the answer in this question: How many decimal Places in A Double (Java)
Answers show within others two ways to solve this quite easy: putting the number to a String and checking where in this String the "."-DecimalPoint occurs, or using the BigDecimal type which has a scale()-Method returning the number of decimals.
You shouldn't expect whole perfect code: But here is a hint to achieve this.
Try to use recursion technique instead for loops.
public double multiplyMe(double x, double y)
{
if(y == 0 || x == 0)
return 0;
if(y > 0 && x > 0 )
return (x + multiplyMe(x, y-1)); // multiply positive
if(y < 0 || x < 0 )
return - multiplyMe(x, -y); // multiply negative
}
one more way by using log:
10 raise to power ( sum of log10(x) and log10(y) )
This approach might be easier to understand. You have to add a b times, or equivalently, b a times. In addition, you need to handle 4 different cases where a and b can be either positive or negative.
public int multiply(int a, int b){
int result = 0;
if (a < 0 && b < 0){
for (int i = a; i <= -1; i++)
result-=b;
}
else if (a < 0){
for (int i = 1; i <= b; i++)
result+=a;
}
else if (b < 0){
for (int i = 1; i <= a; i++)
result+=b;
}
else {
for (int i = 1; i <= b; i++)
result+=a;
}
return result;
}
public static void main(String[] args){
System.out.println(multiply(3,-13)); // -39
}
I profiled my code and found that my program spent roughly 85% of the time executing this particular recursive function. The function aims to calculate the probability of reaching a set of states in a markov chain, given an initial position (x,y).
private static boolean condition(int n){
int i = 0;
while ( n >= i){
if( n == i*4 || n == (i*4 - 1))
return true;
i++;
}
return false;
}
public static double recursiveVal(int x, int y, double A, double B){
if(x> 6 && (x- 2 >= y)){ return 1;}
if(y> 6 && (y- 2 >= x)){ return 0;}
if(x> 5 && y> 5 && x== y){ return (A*(1-B) / (1 -(A*B) - ((1-A)*(1-B))));}
if(condition(x+ y)){
return (recursiveVal(x+1, y,A,B)*A + recursiveVal(x, y+1,A,B)*(1-A));
}
else{
return (recursiveVal(x+1, y,A,B)*(1-B) + recursiveVal(x,y+1,A,B)*B);
}
}
I was once told that 99% of recursive functions could be replaced by a while loop. I'm having trouble doing this though. Does anyone know how I could improve the execution time or rewrite this as a iterative loop?
Thanks
You could try to use a technique called memoization which basically caches previously computed results for recursive calls.
Wikipedia article on memoization.
As a side note, I recommend reformatting your code a bit. Here is a simplified version of yoru code.
private static boolean condition(int n){
for (int i = 0; i <= n; i++)
if(n == i*4 || n == (i * 4 - 1))
return true;
return false;
}
public static double recursiveVal(int x, int y, double A, double B){
if (x > 6 && (x - 2 >= y))
return 1;
if (y > 6 && (y - 2 >= x))
return 0;
if(x > 5 && y > 5 && x == y)
return A*(1-B) / (1 -(A*B) - ((1-A)*(1-B)));
double val1 = recursiveVal(x+1, y, A, B);
double val2 = recursiveVal(x, y+1, A, B);
return condition(x + y)
? A * val1 + val2 * (1-A)
: (1-B) * val1 + B * val2;
}
If you want to refactor a recursive function to an iterative one the steps are as follows:
1) Determine the base case of the Recursion. Base case, when reached, causes Recursion to end. Every Recursion must have a defined base case. In addition, each recursive call must make a progress towards the base case (otherwise recursive calls would be performed infinitely).
2) Implement a loop that will iterate until the base case is reached.
3) Make a progress towards the base case. Send the new arguments to the top of the loop instead to the recursive method.
Example of how trying to understand what it is doing can make the code faster/simpler...
This method is trying to determine if 'n' is a multiple of 4 or n+1 is a multiple of 4. This can be written much shorter as.
private static boolean condition(int n){
return (n+1) & 3 <= 1;
}
To convert this to an iterative form, note that you are computing a function on two (discrete) variables. You can use a table to store the values of the function, and fill in the table in a specific order so that you have already computed values you need by the time you need them. (in this case, from higher values of x and y).
In this case, the boundary cases (corresponding to the base cases in the original recursion) are:
f(7, y..5), f(8, 6)
f(x..5, 7), f(6, 8)
f(7, 7)
Then we fill in f(7, 6) and f(6, 7) and then proceed "downwards" - i.e.
f(6, 6), f(5, 6) ... f(x, 6), f(6, 5), f(5, 5) ... f(x, 5) ... f(x, y).
Note that what looks like function call syntax corresponds to a table lookup (it really converts to array syntax).