I am trying to better understand recursion. I am writing a basic geometric series method which I know could be done easier with a loop but that is not the purpose. The method is producing the currect output for the values of 0 and 1 which is simply 1 and 1.5. But for 2 it is outputting 1.25 when it should be 1.75. Any pointers on a better way to approach this?
public static double geometricSum(int n) {
if(n == 0){
return 1;
}
n = n * 2;
return 1.0 / n + geometricSum((int) (1/Math.pow(2, n)));
}
This happens because you are casting a float into a int.
1/(2^2)=1/4=0.25 --> 0
As you are passing your float as an int you're not getting your thing working propperly.
So 0.25 + geometricSum(0)=1.25.
On the first one happens the same. you pass the 0.5, but turned into an int so you.re not getting your aproximation propperly done.
As an advice, ALWAYS put () on your math functions in order to make the program, and you yourself, understand in which order it computes the numbers.
The first problem is the cast to int, giving the wrong result, already described by reyeselda95.
There is a second problem hidden, which is that if you fix that you get this:
public static double geometricSum(double n) {
System.err.println("Calling with " + n);
if(n == 0){
return 1;
}
n = n * 2;
return 1.0 / n + geometricSum((1/Math.pow(2, n)));
}
Calling this with the provided value of 2, leads to a loop between calls with the following values, leading to a stack overflow.
...
Calling with 0.4999999999999999
Calling with 0.5000000000000001
Calling with 0.4999999999999999
Calling with 0.5000000000000001
...
This may be the function you are looking for, if I understand correctly:
public static double geometricSum(int count) {
if (count == 0) {
return 1;
}
return geometricSum(count-1) + Math.pow(2, -count);
}
Don't cast float to int;
When using float, are you sure your formula is correct? The recursion breaks if an argument is zero, but you will get StackOverflowError when passing the result of 1.0/Math.pow(2, n) to the function.
This is my python code:
def geometricSum(k):
if k == 0:
return 1
return 1/2**k + geometricSum(k-1)
k = int(input())
print(geometricSum(k))
This is all about the power of 2 i.e. 2 Pow n where n is an integer.
Here Recursion is used to get the sequence of values for n.
In my case I've to calculate the value for 1/(2 pow n).
Related
Hi I am making a method that can take an integer as a parameter and compute how many zeros its binary form has. So for example, if I have binaryZeros(44), its binary form is 101100. Therefore, binaryZeros(44) should return 3. However, I am making some errors and I cannot tell where it is coming from. I would appreciate it if someone can point out where I am making that error, or if my approach (logic) to this problem is good enough. Thank you!
My code is Below:
public static int binaryZeros(int n) {
int zeroCount = 0;
double m = n;
while (m >= 0.0) {
m = m / 2.0;
if (m == Math.floor(m)) {
zeroCount++;
} else {
m = Math.floor(m);
}
}
return zeroCount;
}
Below is a more concise way to solve this problem
public static int binaryZeros(int n) {
int zeroCount = 0;
// Run a while loop until n is greater than or equals to 1
while(n >= 1)
{
/* Use modulo operator to get the reminder of division by 2 (reminder will be 1 or 0 as you are dividing by 2).
Keep in mind that binary representation is an array of these reminders until the number is equal to 1.
And once the number is equal to 1 the reminder is 1, so you can exit the loop there.*/
if(n % 2 == 0)
{
zeroCount++;
}
n = n / 2;
}
return zeroCount;
}
Your approach is good, but I think there's a better way to do it. The Integer class has a static method that returns the binary of a number: Integer.toBinaryString(num) . This will return a String.
Then, you can just check if there are any 0 in that string with method that has a for loop and evaluating with an if:
public int getZeros(String binaryString){
int zeros = 0;
for(int i=0; i < binaryString.length; i++)
if(binaryString.charAt[i].equals('0')
zeros++;
return zeros;
}
I believe this would be a simpler option and it doesn't have any errors.
Once m == 0.0, it will never change, so your while loop will never stop.
If you start with a number m >= 0, it can never become negative no matter how many times you divide it by 2 or use Math.floor. The loop should stop when m reaches 0, so change the condition to while (m > 0.0).
Note that you could do the same thing with built-in standard library methods. For example, there is a method that returns the number of leading zeros in a number, and a method that returns the number of bits set to 1. Using both you can compute the number of zeros that are not leading zeros:
static int binaryZeros(int n) {
return Integer.SIZE - Integer.numberOfLeadingZeros(n) - Integer.bitCount(n);
}
Here is one way. It simply complements the integer reversing 1's and 0's and then counts the 1 bits. You should not be using floating point math when doing this.
~ complements the bits
&1 masks the low order bit. Is either 1 or 0
>>> shifts right 1 bit including sign bit.
System.out.println(binaryZeros(44) + " (" +Integer.toBinaryString(44) +")");
System.out.println(binaryZeros(-44) + " ("Integer.toBinaryString(-44)+")");
public static int binaryZeros(int v) {
int count = 0;
while (v != 0) {
// count 1 bits
// of ~v
count += (~v)&1;
v >>>=1;
}
return count;
}
Prints
3 (101100)
4 (11111111111111111111111111010100)
Just be simple, whe there's Integer.bitCount(n) method:
public static int binaryZeros(int n) {
long val = n & 0xFFFFFFFFL;
int totalBits = (int)(Math.log(val) / Math.log(2) + 1);
int setBits = Long.bitCount(val);
return totalBits - setBits;
}
public static int getZeros(int num) {
String str= Integer.toBinaryString(num);
int count=0;
for(int i=0; i<str.length(); i++) {
if(str.charAt(i)=='0') count++;
}
return count;
}
The method toBinaryString() returns a string representation of the integer argument as an unsigned integer in base 2. It accepts an argument in Int data-type and returns the corresponding binary string.
Then the for loop counts the number of zeros in the String and returns it.
(This may seem like this was already answered, but I am looking something more specific.) For schoolwork I need to write a method that calculates the different ways a rectangle can be tiled by a domino tile of 2*1. From what I can see, it would be the fibonacci numbers of the area. I wrote code that compiled in the compiler, but not sure it really makes sense and am clueless where to go from here. How would I be able to implement this better?
public static int domino(int n, int m) // the method signature is what I must use according the hw instructions
{
int area = n*m; // calculating the area of the passed in rectangle
int dominoes = area/2; // calculating how many dominos will be needed to cover the area
if (dominoes<=2) { // because fib 1 equals 1 and fib 2 equals 1
return 1;
} //also the stopping point
else {return domino(dominoes-1, 0) + domino(dominoes-2, 0);}
}
I do not need to worry about efficiency for this homework.
You are not correctly computing the Fibonacci numbers using your recursive calls. You are executing:
else {return domino(dominoes-1, 0) + domino(dominoes-2, 0);}
So essentially, in the first recursive call n == (dominoes - 1) and m == 0. This means that calculating the area always results in 0, as multiplying anything by 0 equals 0.
My advice would be to use an extra Fibonacci function like so:
public static int domino(int n, int m) {
// return the fibonacci number of the number of dominoes in the given rectangle
return fib((n * m) / 2);
}
public static int fib(int n) {
if(n <= 2)
// seed values of the fibonacci sequence
return 1;
else
return fib(n - 1) + fib(n - 2);
}
I have written multiple attempts to this problem, but I think this is the closest I could get. This solution makes the method recurse infinitely, because I don't have a base case, and I can't figure it out. The counter++ line is unreachable, and I can't get this to work, and I am very tired. This would be very easy with a loop, but recursion is kind of a new concept to me, and I would be thankful if someone helped me solve this.
public static double pi(int a, double b){
int counter=0;
if (counter %2==0){
return a-(a/(pi(a,b+2)));
counter++;
} else {
return a+(a/(pi(a,b+2)));
counter++;
}
You could pass in another int, say limit, and add this code:
if (b > limit) {
return a;
}
Or you could pass in some tolerance value:
if (pi(a,b+2) < tolerance) {
return a;
}
Whenever you're working with recursion it's good to establish an exit strategy up front.
Here is an implementation that works. Do not use it:
public static double term(double acc, int n, int r) {
if (r-- > 0) {
double sgn = (n % 4 == 1) ? +1.0 : -1.0;
acc += sgn * 4.0 / n;
n += 2;
return term(acc, n, r);
} else {
return acc;
}
}
public static double pi() {
return term(0.0, 1, 1000);
}
The reason not to use it is that this particular infinite series is a particularly poor way of calculating π because it converges very slowly. In the example above event after 1000 iterations are performed it's still only correct to 3 decimal places because the final calculated term is 4 / 1000.
Going much beyond 1000 iterations results in a stack overflow error with little improvement in the accuracy even though the term function is (I think) potentially tail recursive.
I am writing a recursive method that will calculate a multiplicative Fibonacci Sequence. This sequence is similar to a regular Fibonacci Sequence except that instead of adding the two previous numbers to find the next numbers, you instead multiply them. I currently have this method written but instead of returning what I would think the correct result is, the method is returning 0 no matter what the input number is. Any help or ideas would be greatly appreciated.
Here is the method:
public static int fibonacciPower(int n)
{
if(n < 2)
{
return n;
}
else
{
return (fibonacciPower(n-1) * fibonacciPower(n-2));
}
}
You need to return 1
if(n < 2)
{
return 1;
}
This is because, if n becomes 0, you end up multiplying by 0 and in turn your product becomes 0. Thus instead we multiply with 1 in case of n equal to 0 or 1
Is there a java version of matlab's colon operator or linspace? For instance, I'd like to make a for loop for evenly spaced numbers, but I don't want to bother with creating an array of those numbers manually.
For example to get all integers from 1 to 30, in matlab I would type:
1:30
or
linspace(1,30)
For the two variable call, #x4u is correct. The three variable call will be quite a bit harder to emulate.
For instance, i think that linspace(1,30,60) should produce values 1, 1.5, 2, 2.5, 3, 3.5..., or maybe that's the values for linspace(1,30,59)--either way, same problem.
With this format you'll have to do the calculations yourself--Personally I'd create a new object to do the whole thing for me and forget the for loop.
counter=new Linspace(1,30,60);
while(counter.hasNext()) {
process(counter.getNextFloat())
}
or simply
while(float f : new Linspace(1,30,60)) {
process(f);
}
if you have your Linspace object implement Iterable.
Then the inside of the counter object should be pretty obvious to implement and it will easily communicate to you what it is doing without obfuscating your code with a bunch of numeric calculations to figure out ratios.
An implementation might be something like this:
(NOTE: Untested and I'm pretty sure this would be vulnerable to edge cases and floating point errors! It also probably won't handle end < start for backwards counting, it's just a suggestion to get you going.)
public class Linspace {
private float current;
private final float end;
private final float step;
public Linspace(float start, float end, float totalCount) {
this.current=start;
this.end=end;
this.step=(end - start) / totalCount;
}
public boolean hasNext() {
return current < (end + step/2); //MAY stop floating point error
}
public float getNextFloat() {
current+=step;
return current;
}
}
Do you want to do this?
for( int number = 1; number <= 30; ++number )
If you need them spaced by a fixed amount, i.e. 3 you can write it this way:
for( int number = 1; number <= 30; number += 3 )
The left part of the for loop initializes the variable, the middle part is the condition that gets evaluated before each iteration and the right part gets executed after each iteration.
I actually just had to do this for a java project I am working on. I wanted to make sure it was implemented in the same way as in MATLAB, so I first wrote a MATLAB equivalent:
function result = mylinspace(min, max, points)
answer = zeros(1,points);
for i = 1:points
answer(i) = min + (i-1) * (max - min) / (points - 1);
end
result = answer;
I tested this against the built-in linspace function and it returned the correct result, so I then converted this to a static java function:
public static double[] linspace(double min, double max, int points) {
double[] d = new double[points];
for (int i = 0; i < points; i++){
d[i] = min + i * (max - min) / (points - 1);
}
return d;
}
In my opinion this is much simpler than creating a new class for this one function.
I think Bill K got the right idea, but I think there is no need to have a Linspace class.
// If you write linspace(start,end,totalCount) in Matlab ===>
for(float i = start; i < end; i += (end-start)/totalCount)
something(i);
I was myself looking for a solution for this problem and investigated how MatLab implements its Linspace. I more or less converted it to Java and ended up with the method below. As far as I have tested it works quite nicely and you get the endpoints. There is probably floating point errors as with most cases.
I am not sure if there are Copyright issues with this though.
public static List<Double> linspace(double start, double stop, int n)
{
List<Double> result = new ArrayList<Double>();
double step = (stop-start)/(n-1);
for(int i = 0; i <= n-2; i++)
{
result.add(start + (i * step));
}
result.add(stop);
return result;
}
If you'd like to use Java Streams, one option would be:
public static Stream<Double> linspace(double start, double end, int numPoints) {
return IntStream.range(0, numPoints)
.boxed()
.map(i -> start + i * (end - start) / (numPoints - 1));
}
Here's the main algo that works for matlab, you may convert this to Java with all the OOP details at your disposal:
>>> st=3;ed=9;num=4;
>>> linspace(st,ed,num)
ans =
3 5 7 9
>>> % # additional points to create (other than 3)
>>> p2c=num-1;
>>> % 3 is excluded when calculating distance d.
>>> a=st;
>>> d=ed-st;
>>> % the increment shall calculate without taking the starting value into consideration.
>>> icc=d/p2c;
>>> for idx=[1:p2c];
a(idx+1)=a(idx)+icc;
end;
>>> a
a =
3 5 7 9
>>> diary off