So I have this programming project in which I need to create a program that determines if a number is a perfect square, and if so, write it into a .txt document. This is very easy and effective to do with a for loop, however, the instructions for the assignment say that the program should accomplish this using recursion. This is the iterative statement I came up with:
double division;
for (int i = 0; i < inputs.size(); i++) {
division = (Math.sqrt(inputs.get(i)));
if (division == (int)division) {
pw.println(inputs.get(i));
}
}
Where inputs is an ArrayList that is created by reading the inputs of the user.
This solves the problem, but like I said, it needs to be a recursive statement. I know that for recursion I need a base case that will eventually make the method stop calling itself, but I can't figure out what the base case would be. Also, I've seen several examples of converting from iteration to recursion, but all of these examples use a single int variable, and in my case I need to do it with an ArrayList.
Any help would be greatly appreciated
For recursive function, you can use bynary search algorithm:
int checkPerfectSquare(long N,
long start,
long last)
{
// Find the mid value
// from start and last
long mid = (start + last) / 2;
if (start > last)
{
return -1;
}
// Check if we got the number which
// is square root of the perfect
// square number N
if (mid * mid == N)
{
return (int)mid;
}
// If the square(mid) is greater than N
// it means only lower values then mid
// will be possibly the square root of N
else if (mid * mid > N)
{
return checkPerfectSquare(N, start,
mid - 1);
}
// If the square(mid) is less than N
// it means only higher values then mid
// will be possibly the square root of N
else
{
return checkPerfectSquare(N, mid + 1,
last);
}
}
You could use the fact that a square number is the sum of the odd integers. E.g.
1+3 = 4 = 2^2
1+3+5 = 9 = 3^2
1+3+5+7 = 16 = 4^2, etc
public static void main(String[] args) {
for (int i = 1; i < 1000; i++) {
if (isSquare(i)) System.out.println(i);
}
}
public static boolean isSquare(int n) {
if (n==0 || n==1) return true;
return isSquare(n,1,1);
}
private static boolean isSquare(int n, int sum, int odd) {
if (n==sum) return true;
if (n < sum) return false;
odd += 2;
sum += odd;
return isSquare(n, sum, odd);
}
output:
1
4
9
16
25
36
49
64
81
100
121
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729
784
841
900
961
You could recursively check if the square of any smaller int is equal to your input.
public static boolean isSquare(int n) {
if (n==0 || n==1) return true;
return isSquare(n, 1);
}
private static boolean isSquare(int n, int i) {
if (i*i == n) return true;
if (i*i > n) return false;
return isSquare(n,i+1);
}
Related
How would I go about justifying this algorithm is O(log n)?
public static long exponentiation(long x, int n){
if(n == 0){
return 1;
}
else if (n % 2 == 0){
x = exponentiation(x, n / 2);
return x * x;
}
else{
return x * exponentiation(x, n-1);
}
}
Each recursive call to method exponentiation is a multiplication step. Hence you need to count the number of recursive calls. There are several ways to achieve this. I chose to add another parameter to the method.
public static long exponentiation(long x, int n, int count) {
if (n == 0) {
System.out.println("steps = " + count);
return 1;
}
else if (n % 2 == 0) {
x = exponentiation(x, n / 2, count + 1);
return x * x;
}
else {
return x * exponentiation(x, n - 1, count + 1);
}
}
Here is the initial call to method exponentiation
exponentiation(2, 63, 0);
When I run the above code, the following is printed
steps = 11
You can use a static counter as well (without changing the prototype of the function):
public static long counter = 0;
public static long exponentiation(long x, int n){
if(n == 0){
return 1;
}
else if (n % 2 == 0){
x = exponentiation(x, n / 2);
counter++;
return x * x;
}
else{
counter++;
return x * exponentiation(x, n-1);
}
}
However, you need to reset the counter before calling the function each time, i.e., set counter = 0.
Theoretical Analysis
Note that you need to the counter to prove that it is in O(log(n)). To prove the complexity, just you need to find the complexity term by looking at the flow of the code. Suppose T(n) is the number of multiplications for computing x^n. So, based on the written code, T(n) = T(n/2) + 1, if n is even, and T(n) = T(n-1) + 1, if n is odd. Now, at least in one of two consecutive recursions, input n is even. Therefore, at most 2 log(n) is required to reach to n = 0. Because, for each even input, the next input will be halved. So, we can conclude that the algorithm is in O(log(n)).
I have a problem with my homework and i need help please!
Question 1:
Complete the Java methods below so that raiseToPower(x,n) will raise the number x to an integer power n (that is, to calculate the value xn ). Remember that x-n = 1/xn,
and that x0 = 1.
You should do this in the fewest number of steps possible (that is, in O(log n) time).
Give a solution which is non-recursive (iterative):
This is my solution :
public static double raiseToPower (double x, int n) {
double res=1;
boolean neg=false;
if(n<0)
{
neg=true;
}
if(n>0)
for (int i=0;i<n;i++) {
res = res * x;
}
if(neg==true) {
n=n*-1;
for (int i=0;i<n;i++) {
res = res * x;
}
res=1/res;
}
return res;
}
but this is not correct because is not efficiency
This my error for example:
52.49 to the power of 9 solved in 9 steps, but it could have been done in 4 steps
89.89 to the power of 75 solved in 75 steps, but it could have been done in 7 steps
78.57 to the power of 63 solved in 63 steps, but it could have been done in 6 steps
70.17 to the power of 44 solved in 44 steps, but it could have been done in 6 steps
Note:must not be used in method java.lang.MathPow
Question 2:
I need write code exactly like Question 1 but in recursive
This is my Question:
Give a recursive solution:
This is my code:
public static double raiseToPower (double x, int n) {
ouble dev=0.0;
if (n == 0) {
return 1;
} else {
if (n < 0) {
double count= raiseToPower (x, n+1);
dev=count*x;
return 1 / raiseToPower (x, -n);
}
if (n > 0) {
double count= raiseToPower (x, n-1);
dev=count*x;
}
}
return dev;
}
This code is correct but not efficiency.
This is my error for example:
53.31 to the power of 44 solved in 44 steps, but it could have been done in 6 steps
6.90 to the power of 74 solved in 74 steps, but it could have been done in 7 steps
80.76 to the power of 76 solved in 76 steps, but it could have been done in 7 steps
51.44 to the power of 86 solved in 86 steps, but it could have been done in 7 steps
76.26 to the power of 50 solved in 50 steps, but it could have been done in 6 steps
63.53 to the power of 93 solved in 93 steps, but it could have been done in 7 steps
Note:must not be used in method java.lang.MathPow
Thank you everyone for helping and solving both problems !!!
You can calculate in O(logN) x^n by breaking down n in 2's powers, like so:
9 = 1+8
15= 1+2+4+8
Therefore, x^9= (x^1)*(x^8).
In order to break down n in 2's powers, you can use bitwise operators. Like this: n&pow2 would mean you do the "AND" operation between N and pow2, which means if n has a bit 1 and pow2 also has that bit 1, the result will be non-zero. Given that pow2 must have a single bit 1( it is a power of 2), you can basically check every bit of n. So you are breaking down n in the powers of 2 and you can simply keep a powx around that means x^(pow2) as you are looping through the powers of 2, then multiply it to res whenever you find that n indeed is composed of that power of 2.
So we can make this code for the first solution:
public static double raiseToPower (double x, int n) {
double res=1;
double powx=x;
int pow2=1;
boolean neg=false;
if(n<0)
{
neg=true;
n=n*-1;
}
while(n!=0) {
if((n&pow2)!=0)
{
res=res*powx;
n=n-pow2;
}
powx=powx*powx;
pow2=pow2*2;
}
if(neg==true)
res=1/res;
return res;
}
Here's more articles about bitwise operators: https://www.tutorialspoint.com/java/java_basic_operators.htm
Similarly, you can modify the recursive code to get it in O(logN).
Here would be the recursive code:
public static double raiseToPower(double x, int n)
{
boolean neg= false;
double res=1;
if(n<0)
{
neg=true;
n=-n;
}
if (n == 0) return 1;
if (n % 2 == 0)
{
res= raiseToPower(x, n / 2);
res=res*res;
}
else
{
res= x * raiseToPower(x, n - 1);
}
if(!neg)
return res;
return 1/res;
}
public class ExponentialCalculator {
public static void main(String[] args) {
double x = 2;
int n = -4;
System.out.println(raiseToPower(x, n));
}
//Divide and Conquer method
public static double raiseToPower (double x, int n) {
if(n==0) {
return 1;
}
double temp = raiseToPower(x, n/2) * raiseToPower(x, n/2);
if(n%2==0) {
return n > 0 ? temp: 1/temp;
}
else {
return n > 0 ? x * temp: 1/(x * temp);
}
}
}
result 0.0625
Complexity Log(n)
I made this method for an assignment in class. To count the number of '1's appearing in any given number. I would like to expand on this and learn how to take a number and if it is even number adds one to it. If it is an odd number subtract one from it using recursion and return that changed number.
public static int countOnes(int n){
if(n < 0){
return countOnes(n*-1);
}
if(n == 0){
return 0;
}
if(n%10 == 1){
return 1 + countOnes(n/10);
}else
return countOnes(n/10);
}
0 would = 1 27 would = 36 so on. I would appreciate any help that is given.
You quite often find that using private method in a recursive solution makes your code much clearer.
/**
* Twiddles one digit.
*/
private static int twiddleDigit(int n) {
return (n & 1) == 1 ? n - 1 : n + 1;
}
/**
* Adds one to digits that are even, subtracts one from digits that are odd.
*/
public static int twiddleDigits(int n) {
if (n < 10) return twiddleDigit(n);
return twiddleDigits(n / 10) * 10 + twiddleDigit(n % 10);
}
The Fibonacci sequence is a set of Numbers where each number, after the first two, is the sum of the previous two numbers, resulting in the following sequence:
0 1 1 2 3 5 6 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
How can I write a method, using recursion, which will return a specified fibonacci number? I want to avoid using an array
Here is what i have so far
public static int fibo(int n)
{
if (n==1)
return 1;
else
return //this is the part i am stuck on
As a certain fibonacci number (except 1) is on its percursor you call:
public static int fibo(int n) {
if (n < 0) {
throw new IndexOutOfBoundsException("Can't calculate fibonacci number for negative index");
} else if(n == 0 || n == 1) {
return n;
}
return fibo(n-1) + fibo(n-2);
}
public static int fibo(int n){
if(n<=2)
return (n-1);
else
return fibo(n-1) + fibo(n-2);
}
Each fibonacci number is the sum of its 2 predecessors. You can't just have a base case of n=1 since when calculating n = 2 you will find it is the sum of n = 1 and n = 0? which would not be defined.
Note: This is assuming you are 1-indexing the list of fib numbers i.e 0 is the first 1 the second then 1 the third etc.
public class Fibonacci
{
public static int fibonacci(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
public static void main(String[] args)
{
System.out.println(fibonacci(11));
}
}
public class symm
{
/*
* Returns true if array A is symmetric.
* Returns false otherwise.
* n is the number of elements A contains.
*
* The running time of your algorithm is O( ).
* You may add a brief explanation here if you wish.
*/
public static boolean symmetric( int[] A, int n )
{
return symmHelper(A, n, 0);
}
private static boolean symmHelper(int[] A, int n, int i) {
if(n==1)
return true;
if((n==2) && (A[i] == A[n-1-i]))
return true;
if((i == n-1-i) && (A[i] == A[n-1-i] ))
return true;
if(A[i] == A[n-1-i] && i < n/2 )
return symmHelper(A, n, i+1);
return false;
}
}
Test cases:
I passed all the tests ecxept the fitst on I get no whenever I run it, I think the problem is that there are two 2s in the middle. And I'm not really sure about the code, I think it can be simplified.
Is the running time o(log n)?
5 8 2 2 8 5
YES
10 7 50 16 20 16 50 7 10
YES
5 8 5
YES
1000 1000
YES
6000
YES
10 7 50 16 20 16 50 7 1000
NO
10 7 50 16 20 16 50 700 10
NO
10 7 50 16 20 16 5000 7 10
NO
10 7 50 16 20 1600 50 7 10
NO
10 7 50 16 1600 50 7 10
NO
Complex code makes for more mistakes. Thus, simplify it. Also, look for inequalities rather than equalities; it's easier to check for one mistake than for everything to be correct.
// A = array, n = size of array, i = looking at now
private static boolean symmHelper(int[] A, int n, int i) {
if (i > n/2) // If we're more than halfway without returning false yet, we win
return true;
else if (A[i] != A[n-1-i]) // If these two don't match, we lose
return false;
else // If neither of those are the case, try again
return symmHelper(A, n, i+1);
}
If I remember my O() notation right, I think this should be O(n+1). There are other tweaks you can make to this to remove the +1, but it'll make the code run slower overall.
if(A[i] == A[n-1-i] && i < n/2 )
That line right there is the problem. Because you're using an even number > 2 of values, when it gets to this line it skips over it because at that point i = n/2, rather than being less than it. So the function skips that and continues on to return false. Change it to this and you should be fine:
if(A[i] == A[n-1-i] && i <= n/2 )
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int N;
int i;
boolean sym = true;
N=input.nextInt();
int [] numbers = new int [N];
for (i=0; i<N; i++){
numbers[i]= input.nextInt();
}
for(i=0;i<N;i++){
if(numbers[i]!= numbers[N-1-i]){
sym=false;}
}
if(sym==true){
System.out.println("The array is a symetrical array");
}
else{
System.out.println("The array is NOT a symetrical array");
}
}
}
This check is useless:
if((i == n-1-i) && (A[i] == A[n-1-i] ))
return true;
Of course if the two indices are the same the values there will match.
Also you need to split this if in two:
if(A[i] == A[n-1-i] && i < n/2 )
return symmHelper(A, n, i+1);
And return true if i >= n/2.
Otherwise what happens is that after i > n/2 (which means you already know your array is symmetrical), you do not go into that if and thus return false, which is wrong.
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int N;
int i;
N=input.nextInt();
int [] numbers = new int [N];
for (i=0; i<N; i++){
numbers[i]= input.nextInt();
}
i=0;
while (i<N/2&& numbers[i] == numbers [N-1-i]){i++;
}
if(i==N/2){
System.out.println("The array is a symetrical array");
}
else{
System.out.println("The array is NOT a symetrical array");
}
}