Is this implementation of gcd correct - java

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.)

Related

How to reverse an integer?

I have a code to reverse an integer, but it does not work, can't seem to find the bug.
public static void test(int N) {
int enable_print = N % 10;
while (N > 0) {
if (enable_print == 0 && N % 10 != 0) {
enable_print = 1;
} else if (enable_print == 1) {
System.out.print(N % 10);
}
N = N / 10;
}
}
Sometimes it is easier and/or better to rewrite instead of debugging.
Write or think of your algorithm in pseudocode where each high level step is then broken down into more pseudocode. Your conditions seem strange and therefore hard to debug.
It is best not to embed a print directly into the heart of a loop. Rather, build a string and return it. Let the caller print a string.
System.out.println (reverseInt (12345));
public static String reverseInt (anInt) {
Initialize a StringBuffer with an empty string.
while (anInt > 0) {
Get last digit by modulo 10 and put in StringBuffer.
Prepend digit in StringBuffer.
Chop off last digit by doing integer divide.
}
return StringBuffer's .toString ();
}
An alternate algorithm would call reverseInt recursively to build an ever growing string.
if and else if both works together in a sequence from top to down
if(true) { execute } else if() { done execute even if condition is true } else { done execute}
if(false) else if(check condition) { if true execute other wise go to next condition}
So on..
in your case, this is going to be solution
public static void test(int N) {
int enable_print = N % 10;
while (N > 0) {
if (enable_print == 0 && N % 10 != 0) {
enable_print = 1;
}
if (enable_print == 1) {
System.out.print(N % 10);
}
N = N / 10;
}
}

count uppercase chars in string recursively

I have to solve an exercise, counting all the uppercase chars in a String - recursively - Anyhow I thought I might have found a solution - but it won't work…
Probably you might help me? Thanks!
public static int CountCapitals(String s) {
int counter = 0;
// if (Character.isUpperCase(s.charAt(0)))counter+=1;
if (s.length() == 0)
return counter;
if (s.length() == 1 && s.charAt(0) < 65 && s.charAt(0) > 90)
return 0;
if (s.charAt(0) < 'A' && s.charAt(0) > 'Z') {
return CountCapitals(s.substring(1));
}
if (s.charAt(0) >= 'A' && s.charAt(0) <= 'Z')
counter++;
return CountCapitals(s.substring(1));
}
The problem with your code is the use of counter: each level of invocation has its own counter, initially set to zero. The ++ operator at the bottom has no effect.
You need to compute the result of this invocation based on the result of the previous invocation. Your base case (i.e. s.length() == 0) is fine; the rest of your code needs to change so that it returns whatever CountCapitals(s.substring(1)) when the first letter is non-capital; when the first letter is capital, your function should return 1 + CountCapitals(s.substring(1)).
You need to consider the case when the length of string is 1 and the only character is uppercase (in this case, you should return 1).
Also you need to pass in the counter as a parameter rather than expecting it to "carry over" into other function calls.
This recursion should do just what you want:
public static int countCapitals(String s) {
if (s.length() == 0) return 0;
int cap = Character.isUpperCase(s.charAt(0)) ? 1 : 0;
return countCapitals(s.substring(1)) + cap;
}
If this wasn't a home assignment, you could try an iterative approach which is about 5-10 times faster:
public static int countCapitals(String s) {
int count = 0;
for (int idx = 0; idx < s.length(); idx++) {
if (Character.isUpperCase(s.charAt(idx))) {
count++;
}
}
return count;
}
You don't really need to use a counter variable to keep track of the number of capitals. Instead, you can just the recursive calls, themselves, to keep track of the total:
public static int CountCapitals(String s)
{
if (s.length() == 1)
return (Character.isUpperCase(s.charAt(0)) ? 1 : 0);
else
return CountCapitals(s.substring(1)) +
(Character.isUpperCase(s.charAt(0)) ? 1 : 0);
}
If this is for an assignment and you have to use ASCII values, then fine, but if not, you really should just Character.isUpperCase(char c). In case you're not familiar with the conditional operator, it's defined as follows:
if(someExpression == true)
{
//output 1
}
else
{
//output 0
}
is represented succinctly as:
(someExpression == true) ? 1 : 0
NB:
In your example, counter is set to 0 at the beginning of each method call, so that's why it's not working. If you really want to use a counter, pass it as a parameter to the method instead, and update the parameter with each method call. When you get to the end of the String, simply return the parameter.
You try this
public class HelloWorld{
public static int isUpperCase(String str){
if(str.length()==0) return 0;
boolean check =Character.isUpperCase(str.charAt(0));
if(check){
return isUpperCase(str.substring(1))+1;
}
return isUpperCase(str.substring(1));
}
public static void main(String []args){
String n= "FSAsdsadASdcCa";
System.out.println(isUpperCase("FSAsdsadASdcCa"));
}
}

Recursion - returning a new number with bigger digits than the parameter

I have an exercise in which I have to write a recursive method that receives an integer and a digit d. This method has to return a new number, consisting only digits which is bigger than d.
for example, for the number 19473, and the digit 3, the returned number will be 947.
So far I haven't gotten some progress in my code, so I don't have anything to show you.
The method's signature:
public static int filter(int n, int d)
Any help would be great,
Thank you.
public static int filter(int n, int d)
{
if (n==0) return 0;
if (n%10>d) return 10*filter(n/10,d)+n%10;
else return filter(n/10,d);
}
The key to understand:
A integer n(n>10), assume a=n/10 b=n%10.
You can see filter(n)=(String)filter(a)+(String)filter(b) (I mean,convert the result to string and concatenate the two strings. It's not valid in syntax, it's just for understanding it).
But we don't need to get hands dirty with String, arithmetics will do the same job for integers.
Here is your answer in great details:
int filter(int n, int d) {
if (n >= 0 && d >= 0) { // n and d non-negetive
if (n == 0) { // terminating criteria
return 0;
} else {
int currDigit = n % 10;
if (n % 10 > d) {
return filter(n / 10, d) * 10 + currDigit; //gathering digits greater thand d
} else {
return filter(n / 10, d); // ignoring digits less than or equal d
}
}
}
return -1;
}
One thing you should know, If you are new in coding and want to be a great coder! My advice to you is, don't take away the opportunities from your brain to think about the coding problems! Always trust your brain. Keep patient. Try and try again.
Cheers and Happy coding!

Very simple prime number test - I think I'm not understanding the for loop

I am practicing past exam papers for a basic java exam, and I am finding it difficult to make a for loop work for testing whether a number is prime. I don't want to complicate it by adding efficiency measures for larger numbers, just something that would at least work for 2 digit numbers.
At the moment it always returns false even if n IS a prime number.
I think my problem is that I am getting something wrong with the for loop itself and where to put the "return true;" and "return false;"... I'm sure it's a really basic mistake I'm making...
public boolean isPrime(int n) {
int i;
for (i = 2; i <= n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
The reason I couldn't find help elsewhere on stackoverflow is because similar questions were asking for a more complicated implementation to have a more efficient way of doing it.
Your for loop has a little problem. It should be: -
for (i = 2; i < n; i++) // replace `i <= n` with `i < n`
Of course you don't want to check the remainder when n is divided by n. It will always give you 1.
In fact, you can even reduce the number of iterations by changing the condition to: - i <= n / 2. Since n can't be divided by a number greater than n / 2, except when we consider n, which we don't have to consider at all.
So, you can change your for loop to: -
for (i = 2; i <= n / 2; i++)
You can stop much earlier and skip through the loop faster with:
public boolean isPrime(long n) {
// fast even test.
if(n > 2 && (n & 1) == 0)
return false;
// only odd factors need to be tested up to n^0.5
for(int i = 3; i * i <= n; i += 2)
if (n % i == 0)
return false;
return true;
}
Error is i<=n
for (i = 2; i<n; i++){
You should write i < n, because the last iteration step will give you true.
public class PrimeNumberCheck {
private static int maxNumberToCheck = 100;
public PrimeNumberCheck() {
}
public static void main(String[] args) {
PrimeNumberCheck primeNumberCheck = new PrimeNumberCheck();
for(int ii=0;ii < maxNumberToCheck; ii++) {
boolean isPrimeNumber = primeNumberCheck.isPrime(ii);
System.out.println(ii + " is " + (isPrimeNumber == true ? "prime." : "not prime."));
}
}
private boolean isPrime(int numberToCheck) {
boolean isPrime = true;
if(numberToCheck < 2) {
isPrime = false;
}
for(int ii=2;ii<numberToCheck;ii++) {
if(numberToCheck%ii == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
}
With this code number divisible by 3 will be skipped the for loop code initialization.
For loop iteration will also skip multiples of 3.
private static boolean isPrime(int n) {
if ((n > 2 && (n & 1) == 0) // check is it even
|| n <= 1 //check for -ve
|| (n > 3 && (n % 3 == 0))) { //check for 3 divisiable
return false;
}
int maxLookup = (int) Math.sqrt(n);
for (int i = 3; (i+2) <= maxLookup; i = i + 6) {
if (n % (i+2) == 0 || n % (i+4) == 0) {
return false;
}
}
return true;
}
You could also use some simple Math property for this in your for loop.
A number 'n' will be a prime number if and only if it is divisible by itself or 1.
If a number is not a prime number it will have two factors:
n = a * b
you can use the for loop to check till sqrt of the number 'n' instead of going all the way to 'n'. As in if 'a' and 'b' both are greater than the sqrt of the number 'n', a*b would be greater than 'n'. So at least one of the factors must be less than or equal to the square root.
so your loop would be something like below:
for(int i=2; i<=Math.sqrt(n); i++)
By doing this you would drastically reduce the run time complexity of the code.
I think it would come down to O(n/2).
One of the fastest way is looping only till the square root of n.
private static boolean isPrime(int n){
int square = (int)Math.ceil((Math.sqrt(n)));//find the square root
HashSet<Integer> nos = new HashSet<>();
for(int i=1;i<=square;i++){
if(n%i==0){
if(n/i==i){
nos.add(i);
}else{
nos.add(i);
int rem = n/i;
nos.add(rem);
}
}
}
return nos.size()==2;//if contains 1 and n then prime
}
You are checking i<=n.So when i==n, you will get 0 only and it will return false always.Try i<=(n/2).No need to check until i<n.
The mentioned above algorithm treats 1 as prime though it is not.
Hence here is the solution.
static boolean isPrime(int n) {
int perfect_modulo = 0;
boolean prime = false;
for ( int i = 1; i <= n; i++ ) {
if ( n % i == 0 ) {
perfect_modulo += 1;
}
}
if ( perfect_modulo == 2 ) {
prime = true;
}
return prime;
}
Doing it the Java 8 way is nicer and cleaner
private static boolean isPrimeA(final int number) {
return IntStream
.rangeClosed(2, number/2)
.noneMatch(i -> number%i == 0);
}

How to rewrite Ackermann function in non-recursive style?

I have function
public static int func(int M,int N){
if(M == 0 || N == 0) return M+N+1;
return func(M-1, func(M, N-1));
}
How to rewrite it in non-recursive style ?
Maybe, is it implementation some algorithm?
Not quite O(1) but definitely non-recursive.
public static int itFunc(int m, int n){
Stack<Integer> s = new Stack<Integer>;
s.add(m);
while(!s.isEmpty()){
m=s.pop();
if(m==0||n==0)
n+=m+1;
else{
s.add(--m);
s.add(++m);
n--;
}
}
return n;
}
All the answers posted previously don't properly implement Ackermann.
def acker_mstack(m, n)
stack = [m]
until stack.empty?
m = stack.pop
if m.zero?
n += 1
elsif n.zero?
stack << m - 1
n = 1
else
stack << m - 1 << m
n -= 1
end
end
n
end
This looks like homework, so I won't give you the answer but I will lead you in the right direction:
If you want to breakdown the recursion, it might be useful for you to list out all the values as they progress, letting m = {0...x} n = {0...y}.
For example:
m = 0, n = 0 = f(0,0) = M+N+1 = 1
m = 1, n = 0 = f(1,0) = M+N+1 = 2
m = 1, n = 1 = f(1,1) = f(0,f(1,0)) = f(0,2) = 3
m = 2, n = 1 = f(2,1) = f(1,f(2,0)) = f(1,3) = f(0,f(1,2)) = f(0,f(0,f(1,1))
= f(0,f(0,3)) = f(0,4) = 5
With this, you can come up with a non-recursive relationship (a non-recursive function definition) that you can use.
Edit: So it looks like this is the Ackermann function, a total computable function that is not primitive recursive.
This is the a correct version which already examined by myself.
public static int Ackermann(int m, int n){
Stack<Integer> s = new Stack<Integer>;
s.add(m);
while(!s.isEmpty()){
m=s.pop();
if(m==0) { n+=m+1; }
else if(n==0)
{
n += 1;
s.add(--m);
}
else{
s.add(--m);
s.add(++m);
n--;
}
}
return n;
}
I couldn't get #LightyearBuzz's answer to work, but I found this Java 5 code from WikiWikiWeb that worked for me:
import java.util.HashMap;
import java.util.Stack;
public class Ackerman {
static class Pair <T1,T2>{
T1 x; T2 y;
Pair(T1 x_,T2 y_) {x=x_; y=y_;}
public int hashCode() {return x.hashCode() ^ y.hashCode();}
public boolean equals(Object o_) {Pair o= (Pair) o_; return x.equals(o.x) && y.equals(o.y);}
}
/**
* #param args
*/
public static int ack_iter(int m, int n) {
HashMap<Pair<Integer,Integer>,Integer> solved_set= new HashMap<Pair<Integer,Integer>,Integer>(120000);
Stack<Pair<Integer,Integer>> to_solve= new Stack<Pair<Integer,Integer>>();
to_solve.push(new Pair<Integer,Integer>(m,n));
while (!to_solve.isEmpty()) {
Pair<Integer,Integer> head= to_solve.peek();
if (head.x.equals(0) ) {
solved_set.put(head,head.y + 1);
to_solve.pop();
}
else if (head.y.equals(0)) {
Pair<Integer,Integer> next= new Pair<Integer,Integer> (head.x-1,1);
Integer result= solved_set.get(next);
if(result==null){
to_solve.push(next);
}
else {
solved_set.put(head, result);
to_solve.pop();
}
}
else {
Pair<Integer,Integer> next0= new Pair<Integer,Integer>(head.x, head.y-1);
Integer result0= solved_set.get(next0);
if(result0 == null) {
to_solve.push(next0);
}
else {
Pair<Integer,Integer> next= new Pair<Integer,Integer>(head.x-1,result0);
Integer result= solved_set.get(next);
if (result == null) {
to_solve.push(next);
}
else {
solved_set.put(head,result);
to_solve.pop();
}
}
}
}
System.out.println("hash size: "+solved_set.size());
System.out.println("consumed heap: "+ (Runtime.getRuntime().totalMemory()/(1024*1024)) + "m");
return solved_set.get(new Pair<Integer,Integer>(m,n));
}
}
Written in python, using only 1 array and 1 variable, hope this helps!
def acker(m,n):
right = [m]
result = n
i = 0
while True:
if len(right) == 0:
break
if right[i] > 0 and result > 0:
right.append(right[i])
right[i] -= 1
result -= 1
i += 1
elif right[i] > 0 and result == 0:
right[i] -= 1
result = 1
elif right[i] == 0:
result += 1
right.pop()
i -=1
return result
Well I came here to find the answer of this question. But could not write a code even after looking at the answers. So, I tried it myself and after some struggle built the code.
So, I will give you a hint (because I feel etiquettes here are that the homework questions are not meant to be fully answered).
So you can use a single stack to compute the function without using recursion. Just look at the flow of control in David's answer. You have to use that. Just start a while(1) loop and inside that check for the case your arguments are satisfying. Let the desired block amongst if-else blocks execute.Then push the two latest arguments of ackerman function into the stack. Then at the end of the loop pop them and let the cycle repeat till an end condition is reached where no further arguments of ackermann function are generated. You have to put a for statement inside the while loop to keep checking it. And finally get the final results.
I don't know how much of this is understandable, but I wish I could have some idea to start with. So, just shared the way.

Categories

Resources