I have had a long time trying to convert this function into a loop but I can't find the way to do it. I have started with a while(m != 0) and then the conditionals inside, but the third if is the one that won't let me do it.
public static int calculatePayment(int n, int m){
if(m == 0) return n + 1;
if(n == 0 && m > 0) return calculatePayment(1, m - 1);
if(n > 0 && m > 0) return calculatePayment(calculatePayment(n - 1, m), m - 1);
return 0;
}
Also, I don't know is I need to use a BigInteger, aretrograde and inverteds the program will run StackOverFlow Error and won't let me know if I need it.
Edits:
1st:
m cannot be less than zero in the input, that will never happen. Same situation with n, the code doesn't need to handle that.
So far I have this:
while(m > 0){
if(n == 0 && m > 0){n = 1; m--;}
if(n > 0 && m > 0){m--; n = IDONTKNOWWHAT;}//here n is the value of
//the payment if n = n - 1
//and m = m
//here is the big deal.
}
if(m == 0) return n + 1; //or print
Also the code cannot be reduced to a mathematical formula, I tried.
It looks like you're trying to find a non-recursive algorithm for computing the Ackermann's function. I wouldn't mind having my salary computed like that:) I guess its an attempt to disguise a homework?
Anyway, you can just simulate the stack and store intermediate values and then it's quite easy, see: How to rewrite Ackermann function in non-recursive style?
By the way, Ackermann's function grows extremely fast. You could use BigInteger but it would be mostly futile anyway. Exact values of the function are known only for a couple of the smallest arguments. Also, a lot of recursion is involved so you need to cache intermediate values to postpone the StackOverflow, google about memoization.
Related
I am new to Java and am I trying to implement a recursive method for finding "n choose k".
However, I've run into a problem.
public class App {
public static void main(String[] args) throws Exception {
int n = 3;
int k = 2;
int result = combRecursion(n, k);
System.out.println(result);
}
private static int combRecursion(int n, int k) {
if (k == 0) {
return 1;
} else {
return (combRecursion(n - 1, k - 1) + combRecursion(n - 1, k));
}
}
Output:
many repetitions of this line:
at App.combRecursion(App.java:14)
It's possible to pick k items from the set of n items only if n is greater or equal to k.
You need to cut off fruitless branches of recursion spawn by the call combRecursion(n - 1, k) which doesn't reduce the number of item in the sample.
When you need to create a recursive method, it should always contain two parts:
Base case - that represents a set of edge-cases, trivial scenarios for which the result is known in advance. If the recursive method hits the base case (parameters passed to the method match one of the conditions of the base case), recursion terminates. In for this task, the base case will represent a situation when the source list was discovered completely and position is equal to its size (invalid index).
Recursive case - a part of a solution where recursive calls are made and where the main logic resides.
Your recursive case is correct: it spawns two recursive branches of execution (one will "pick" the current item, the second will "reject" it).
But in the base case, you've missed the scenario mentioned above, we need to address these situations:
n isn't large enough (k > n), so that is not possible to fetch k item. And the return value will be 0 (or instead of returning a value, you might throw an exception).
k == 0 result should be 1 (it's always possible to take 0 items, and there's only one way to do it - don't pick anything).
When k == n - there's only one way to construct a combination, as #akuzminykh has pointed out. And the return value will be 1
Note that because your goal is to get familiar with the recursion (I'm pretty sure that you're doing it as an exercise) there's no need to mimic the mathematical formula in your solution, use pure logic.
Here is how you can implement it:
private static int combRecursion(int n, int k) {
if (k > n) return 0; // base case - impossible to construct a combination
if (n == k || k == 0) return 1; // base case - a combination was found
// recursive case
return combRecursion(n - 1, k - 1) + combRecursion(n - 1, k);
}
main() - demo
public static void main(String[] args) {
System.out.println(combRecursion(3, 2));
System.out.println(combRecursion(5, 2));
}
Output
3 // pick 2 item from the set of 3 items
10 // pick 2 item from the set of 5 items
Your base case ought to include both n == k || k == 0 for "n choose k" to be implemented correctly. That way, both calls will eventually terminate (even though your current implementation is rather inefficient as it has exponential runtime). A better implementation would use the formula n!/k!/(n-k)! or the multiplicative formula to run in linear time:
int factorial(int n) {
int res = 1;
for (; n > 1; n--) {
res *= n;
}
return res
}
int choose(int n, int k) {
return factorial(n)/factorial(k)/factorial(n-k);
}
further optimizing this is left as an exercise to the reader (hint: a single for loop suffices).
This is the code for a function that is supposed to return true if the input is prime and returns false if it is not.
This is how I intended for it to work: lets say that y = 7, the loop starts with n=1. Since 1(n) is less that 7(y) the loop can iterate. The program checks if y divided by n has a remainder of 0, meaning that n is a factor of y. If it is true, then it checks to see if the factor does not equal 1 or y (7), because if they dont then that means that y has more factors other than its self and 1, meaning that it is not prime, so it should automatically end the function and return false. but since 7 has only two factors, 1 and 7, and they either equal 1 or itself (y) then after the end of the loop, it should return true.
I don't understand why it isn't working.
public static boolean checkIfPrime(long y) {
for ( long n =1L; n <= y; n++) {
if(y%n == 0) {
if( n != 1L || n != y) {
return false;
}
}
}
return true;
}
With a few optimizations the code will be like this
static boolean isPrime(long n){
long lim = (long) Math.sqrt(n);
if(n%2 == 0 && n != 2)
return false;
for (int i = 3; i <= lim; i=i+2)
if(n%i == 0)
return false;
return true;
}
This code:
checks if the number is even and different from 2 (all even numbers
except 2 are compound).
next iterates from 3 to sqrt(n), thats because to prove a number is
prime you don't need to check all the dividers (if you don't believe
me try, and if still don't believe use n/2 wich is enough but not the
minimum value).
For loop pace start from 3 and add 2 in each iteration getting only odd numbers as divder (we first checked that it wasn't an even number).
Remove equal to operator in n <= y. Start your loop from 2. It must be like this. ( long n =2; n < y; n++)
For what you are trying to achieve, pseudo code in my opinion should look like this:
set a flag = true;
Loop from 2 to y-1{
if(y%n==0){
flag = false
break; // Very important
}
}
check flag condition & return (if some othe computation is required) or just return flag
if( n != 1L || n != y) : is adding a check condition unnecessarily to every iteration. try to avoid it.
Why use a flag instead of direct return statement ? Just a preference, a direct return definitely would work in this case.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Ive used the following function in one of my programs.
I have tried to make sure that my code is efficient however I cannot find any help online to tell me how to recognize where I could improve...
Is there any one that can help identify if there are any parts of this where I could improve (make faster) or run more efficiently
z, s and t are all integers
powerMod(z, s, t) {
int temp = 1;
while (s > 0) {
temp = temp * z;
s = s - 1;
}
temp = temp mod t;
return temp;
}
so the overall function of this is too calculate z to the power of s then mod it by n every time. very simple yet I cannot figure out how i can make this faster as it will be used by main program 100s or 1000s of times
so something like this?
using the exponentiation by square and ive used long just in case of overflow due to int * int...
int powMod(int z, int s, int t){
long result = 1; //int * int will never exceed the size of a long
long multiplicant = z;
while(s > 0){
if(s % 2 == 1) {
result *= multiplicant;
result %= t; // do modulo on each temporary result to keep accuracy
}
multiplicant *= multiplicant;
multiplicant %= t;
s /= 2;
}
return result;
}
First, note that your code will fail to do what you description asks to do for large inputs:
...so the overall function of this is too calculate z to the power of
s then mod it by n every time. ...
However, note that your code will break for large values due to integer overflow, since you will first try to calculate a huge number, which is likely to overflow - and only then you will invoke the mode operator.
The correct way to calculate the above is using the fact that:
(x*x*x*...*x) mod t == (...(((x mod t)*x) mod t)*...*x) mod t
The second calculation will yield the correct answer for much larger inputs, only assumption needed is x*t <= Integer.MAX_VALUE, which is a much simpler assumption.
As for your request to improve performance - the power operator is efficiently calculated using exponent by squaring. Make sure you utilize the above equation in this method as well to avoid mistakes for large inputs.
Another solution is to use java's BigInteger library, specifically the method BigInteger.modPow()
Instead of building your own operator, try using Math.pow() (and add the mod part).
Why not just use Math? Seems like the fastest way to me.
powerMod(double z, double s, double t)
{
double a = Math.pow(z, s);
return Math.floorMod(a, t);
}
If you are really concerned by performance you can use Guava.IntMath.pow() which does exponentiate in O(log(n)) time. Source code of this implementation is below:
public static int pow(int b, int k) {
checkNonNegative("exponent", k);
switch (b) {
case 0:
return (k == 0) ? 1 : 0;
case 1:
return 1;
case (-1):
return ((k & 1) == 0) ? 1 : -1;
case 2:
return (k < Integer.SIZE) ? (1 << k) : 0;
case (-2):
if (k < Integer.SIZE) {
return ((k & 1) == 0) ? (1 << k) : -(1 << k);
} else {
return 0;
}
default:
// continue below to handle the general case
}
for (int accum = 1;; k >>= 1) {
switch (k) {
case 0:
return accum;
case 1:
return b * accum;
default:
accum *= ((k & 1) == 0) ? 1 : b;
b *= b;
}
}
}
You should also note that in most practical cases regular Math.pow() will be enough for your solution. You should think about swapping algorithms if it really slows down your program.
public static int divisor(int m, int n) {
if (m == 0 || n == 0) {
return m+n;
} else {
return divisor(n, m%n);
}
}
It's giving me wrong answers for some input(I don't know which as they don't reveal which input they use for test case) in the amazon.interviewstreet.com
Also why this implementation keeps giving me stackoverflow(again no idea for which inputs)
public static int divisor(int m, int n) {
if(m == 0 || n == 0) {
return m+n;
} else if (m > n) {
return divisor(n, m%n);
} else {
return divisor(m, n%m);
}
}
Please let me know what am I missing. I'm new to programming and am still a beginner.
I think first one is a code for a programming contest. If so be careful with your data types. May be 'int' is not enough to hold the inputs. Try 'long' instead.
(and this will work only if your algorithm is correct.)
I think
return(m, n%m);
should be
return divisor(m, n%m);
Maybe invalid handling of negative values of n and m?
Read e.g. this: Best way to make Java's modulus behave like it should with negative numbers?
for the second part what is
return(m, n%m);
Is this code get compiled ?
use :
public static int divisor(int m, int n) {
if(m == 0 || n == 0)
return m+n;
else if(m>n)
return divisor(n, m%n);
else
return divisor(m, n%m);}
First,
return(m, n%m)
definitely does not compile, I suppose it was meant to be
return divisor(m, n%m);
Second, I guess what is wrong in the second snippet is handling of negative numbers.
Because A and B have the same GCD as -A and -B, I would add
m = Math.abs(m);
n = Math.abs(n);
to the beginning of the method
For the second part :
Also why this implementation keeps giving me stackoverflow(again no idea for which inputs)?
Try this input set :
5
3 1 16 5 10
It will give you the stackoverflow error. For your given code in pastebin.
Why ?
If the input is '1' there will be this problem.
edit your code part like below and see the out put for input (1 1).
public static int divisor(int m, int n) {
System.out.println("### "+m+" "+n);
if (m == 0 || n == 0) {
return m + n;
} else if (m > n) {
return divisor(n, m % n);
} else {
return divisor(m, n % m);
}
}
in some point out put will be like this :
.
.
### 1 1134903170
### 1 0
### 1 1836311903
### 1 0
### 1 -1323752223
### -1323752223 1
### -1323752223 1
### -1323752223 1
.
.
because in your code the function calling is like below.
public static int divFib(int num) {
int i = 1, j = 2, temp;
while (divisor(num, j) == 1) {
temp = j;
j = j + i;
i = temp;
}
return j;
}
divisor(num, j) will be called like divisor(1, 2) then below part will execute
else {
return divisor(m, n % m);
}
the calling will be like divisor(1,0) because n%m = 2%1 =0
then '1' will be return as (m+n = 1).
then while (divisor(num, j) == 1){} will execute again and 'j' will be get increased. But 'num' is '1'. the same thing happens again and again. resulting 'j' to be a huge number and eventually it will assigned a negative number. (I think you know why its happening).
The thing is this will not ever stopped. so the stack will be overflowed due to huge number of function calls.
I think this is a quite clear explanation and if you have any doubt please ask.
(Sorry i mistakenly post the answer here.)
Is there an elegant way in java to check if an int is equal to, or 1 larger/smaller than a value.
For example, if I check x to be around 5. I want to return true on 4, 5 and 6, because 4 and 6 are just one away from 5.
Is there a build in function to do this? Or am I better off writing it like this?
int i = 5;
int j = 5;
if(i == j || i == j-1 || i == j+1)
{
//pass
}
//or
if(i >= j-1 && i <= j+1)
{
//also works
}
Of course the above code is ugly and hard to read. So is there a better way?
Find the absolute difference between them with Math.abs
private boolean close(int i, int j, int closeness){
return Math.abs(i-j) <= closeness;
}
Based on #GregS comment about overflowing if you give Math.abs a difference that will not fit into an integer you will get an overflow value
Math.abs(Integer.MIN_VALUE - Integer.MAX_VALUE) //gives 1
By casting one of the arguments to a long Math.abs will return a long meaning that the difference will be returned correctly
Math.abs((long) Integer.MIN_VALUE - Integer.MAX_VALUE) //gives 4294967295
So with this in mind the method will now look like:
private boolean close(int i, int j, long closeness){
return Math.abs((long)i-j) <= closeness;
}
use Math.abs(x-5) <= 1 as a simple test. However, elegant is in the eye of the beholder. Strive for clarity instead.
Note than in general, for something like Glitch's fine answer or even this, there are overflow conditions that must be analyzed and understood. For correctness over all possible ints you should cast the arguments to long and perform the comparison using longs.