How do I go about figuring out this complicated recursion algorithm? - java

I just started Data Structures and Algorithms which is taught in Java. So far I've only learned C++ in my life so I'm still VERY new to using java.
Anyways I have a homework problem I'm a little stuck on:
Write a recursive method that returns the number of 1's in the binary representation of N. Use the fact that this is equal to the number of 1's in the representation of N/2 + 1, if N is odd.
Now i'm not sure how exactly to do this. I already have a function set up that takes an integer and converts it to binary and stores it in a string, yet the rest I'm kinda lost on.
If I can get some guidance, that would really help.
This is what I have so far:
import java.io.*;
public class Homework1Code {
static void prtbinary(String Molly, int size){
if(size <=0){
return;
}
}
public static void main(String[] args) {
int i = 38;
String binstr = Integer.toBinaryString(i);
System.out.println("The Original Decimal Number is: " + binstr);
prtbinary(binstr, binstr.length());
}
}
Thanks

This is not a hard problem to solve. What you need to do is stop writing code and first solve the problem on paper. Then convert your algorithm to code.

Step one: think!
It is very hard to write a recursive method whose return type is void.

The question is about doing arithmetic, so leave the value as an int rather than convering to a string.
Then there are two facts (for non-negative numbers):
if N is odd then the number of ones is the same as in N/2 plus the one remainder;
if N is even then the number of ones is the same as in N/2.
bitCount of 010101 is bitCount of 010101/2 = 01010 plus 1
bitCount of 010100 is bitCount of 010100/2 = 01010
Rinse and repeat until finished (induction).
Just don't look at the source to Integer.bitCount.

first, reduce the problem to the easiest case ...

Related

I made code to calculate greatest common divisor but there is issue

Hi people I made code to calculate greatest common divisor of 2 number.
It work good but I get many outputs. I want the greatest output but I don't know how to fix it?
What my code do is this here: You enter 2 integer. The first integer must be greater than the second. Now code check second integer first. Is it dividable by 1, 2, 3, 4, 5, .. Then code check all working numbers with first number. In the end we have greatest common divisor.
And before code does all it, it check if second number divide first (in case second is the gcd).
Now my problem: Let's take input 36 and 14. My code will give output
1
2
But how can I avoid code also print all other working numbers? I only want printed the greatest working number but no idea how to implement this in my code? I also don't want copy other code because I did all myself till here and proud:
import java.util.Scanner;
public class Testit{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
double x = input.nextDouble();
double y = input.nextDouble();
double first=0;
first=x/y;
if(first==(int)first){
System.out.println((int)y);
return;
}
else{
for(double i=1; i<x && i<y; i++){
double sum=0;
sum=y/i;
if(sum==(int)sum){
double temp=0;
temp=x/i;
if(temp==(int)temp){
System.out.println((int)i);
}
}
}
}
}
}
Instead of printing, save the result in a temporary variable
double first=0;
int greatestCommonDivisor = 1;
...
if(temp==(int)temp){
greatestCommonDivisor = Double.valueOf(i).intValue();
}
...
System.out.println("Greatest common divisor:" + greatestCommonDivisor);
That said, there are a lot of places your algorithm and code could be improved. For a start you should think about starting at the largest possible number and just stopping when you found the first common divisor (because that would be the greatest) instead of looping through all possible numbers starting from the smallest possible number. And you should have a look at the modulo operation and use integers instead of doubles for your values.
You have to change your code; for example like this:
Currently, your code is simply printing each time it finds a "match".
Instead of printing immediately, you push that value into a helper variable. And in the end; when your loop has ended, you simply print that helper variable!
Then you automatically print the last number that your algorithm computed and stored.
( I am not giving you any code here; just an idea - as you will learn more by writing the code yourself! )

How do I check how many digits my answer has?

I'm trying to find the most precise value by calling a method many times. How can I check when the nth iteration will give a value of precision 8 digits. My method returns a double each time I call it, but I want to stop calling it when the result has 8 digits of accuracy in it.
For example, if I call the method getValue() 20 times, and on the 20th time it has an answer that has 8 digits, how do I check the answer and stop the code?
My method is too long to post, so a general explanation should suffice.
The Problem is as follows:
Use the power method to calculate the largest eigenvalue of the Leslie matrix A. The iteration of the power method should stop when you get 8 digits of accuracy.The Leslie Matrix Model can be written as
n(k + 1) = An(k), k = 0, 1, 2,... and with some n(0) given.
double is never going to be precise enough in this way. The only way to know the accuracy of your answer is by doing a mathematical analysis of the operation you're doing and stopping when the error is guaranteed to be less than a certain amount.
However, there is a little bit of a trick if you know your analysis is going to converge. You can compare successive values, and see how large the difference is. Here's some pseudocode:
while(true) {
nextValue = computeNextValue(previousValue);
if(Math.abs(previousValue - nextValue) < ERROR_THRESHOLD) {
break;
}
previousValue = nextValue;
}
#user58697 makes a great point in the comments:
Even if the sequence converges, successive difference may stop the process too early. Knowing the convergence rate is vital.
Keep this in mind when writing your program.
Honestly, I do not believe that there is a generic answer. How do you know that the answer 7.9999999 is more precise than 8.0 (which could be 8.00000000000000) ? It probably depends very much on the problem you want to solve, I guess.
You may use the following hack to check the fractional part. Here is the complete code -
public class FractionCheck{
public static void main(String[] args){
int length1 = findFractionLegth(423423.98476527);
int length2 = findFractionLegth(428294.31231);
System.out.println(length1);
System.out.println(length2);
}
public static int findFractionLegth(double number){
String numberStr = Double.toString(number);
String fractionalStr = numberStr.substring(numberStr.indexOf('.')+1);
return fractionalStr.length();
}
}
The findFractionLegth(double number) method calculate the fractional part of a double.

Calculate Large Factorials Using Nodes in Java

Okay, so I have been searching the internet and have found many things related to this question. However, I am not able to put the pieces together in order to figure this out.
The requirements are to calculate a large factorial (e.g. 999!) USING LINKED LISTS and NODES. There are many people online that have shown a basic way of calculating a factorial and I understand how to do the factorial part, but the part I am having trouble with is filling each node with an Int between 0-999 (a three digit number) then printing out each node to look like a whole number (including commas).
How can I achieve this?
- My thoughts are to get the result of n! and just do %10, %100,etc.. to break it up and insert the parts into nodes, but that would be pointless because the factorial would have to be completely solved for that to work. So that would be dumb.
The reason for doing this is to learn how to manipulate nodes and linked lists for my Data Structures class.
To me, this a clear explanation, but please let me know if the question is unclear and I will try to explain. Any help will be much appreciated.
(I dont have any code to show besides a basic factorial function that I am using as a bases to build upon).
Okay, I think I understand what you're after.
At the end of this answer is a link to a Gist that solves this problem. I'm not entirely sure it's what you are after, alas... it's my best guess.
The algorithm consists of five steps:
Build the list of factorial members.
Calculate and group Prime Factors of factorial members.
Distribute Prime Factors over powers of 10.
Multiply Prime Factors, carrying overflow up into the next decimal
place.
Print the solution.
It is inspired by the method described here on math.stackexchange.com. I strongly suggest reading both the question and answer linked before examining the Gist.
Now that that's been said, the Gist can be found here. It is very rough, meant only as a quick demonstration of the method.
I hope it helps you. Best of luck.
To calculate a factorial using a LinkedList is a simple 2-stage process.
Stage 1 is to create a LinkedList of all numbers up to the number you want the factorial of. This is a very simple operation that can be achieved with a basic for loop.
List<Integer> list = new LinkedList<Integer>();
for(int i = 1; i <= limit; i++) {
list.add(i);
}
System.out.println(list);
Stage 2 is also relatively easy, using a foreach loop, we iterate over the contents of the list and multiply each element by the product of the previous list elements.
One major concern however, is that the factorial of numbers as large as 999 cannot be held in any of Java's primitive numeric types (int or even long). To hold the factorial, we have to make use of Java's BigDecimal class (Java Docs).
//Stage 2: Calculate the factorial.
BigDecimal factorial = new BigDecimal(1);
BigDecimal factor = null;
for(int n : list) {
factor = new BigDecimal(n);
factorial = factorial.multiply(factor);
}
With those two stages, we can simply print the contents of factorial to see the factorial of your provided number. See the complete code below:
public static void factorial(int limit) {
// Stage 1: Build the list.
List<Integer> list = new LinkedList<Integer>();
for(int i = 1; i <= limit; i++) {
list.add(i);
}
System.out.println(list);
//Stage 2: Calculate the factorial.
BigDecimal factorial = new BigDecimal(1);
BigDecimal factor = null;
for(int n : list) {
factor = new BigDecimal(n);
factorial = factorial.multiply(factor);
}
System.out.println(factorial);
}
We multiply like we actually do with every digit of the number and take take the carry forward. Each digit is stored in a node of the linkedlist. The number is stored in reverse order so that we can multiply without using any extra space.
public static void find(int n) {
Node head=new Node(1);
for(int i=2;i<=n;i++)
multiply(i,head);
print(head);
}
private static void multiply(int k, Node head) {
int carry=0,prod=0;
Node prev=null;
while(head!=null)
{
prod=head.data*k+carry;
head.data=prod%10;
carry=prod/10;
prev=head;
head=head.next;
}
while(carry!=0) {
Node n=new Node(carry%10);
prev.next=n;
carry=carry/10;
prev=prev.next;
}
}
private static void print(Node head) { //printing in reverse order
if(head==null)
return;
print(head.next);
System.out.print(head.data);
}
The concept is best explained here

Fastest way to factor powers of two?

I'm writing some code where I'd like to be able to factorise out powers of two quickly.
I've noticed something handy about numbers with powers of two in them when represented in binary:
27959296 = 0b1101010101010000000000000 = 110101010101 * 10000000000000 = 3413 * 2^13
If I could bitshift those zeros out I'd be left with the other factors. After looking over google, SO and a few other places, and playing with Wolfram|alpha I can't see a good way of doing this without iterating over and dividing by two/bit shifting on each operation. If I convert it into a string I might be able to use string manipulation to split those zeros off.
I've tried using the rule of logs to say that:
log base 2(27959296) = log(3413 * 2^13)/log(2) = 13+ log(3413)/log(2)
But I'm missing the logic that differentiates between the 13 and the log(3413)/log(2) from 24.73.... that would give an 'easy' answer.
Finally there is a method numberOfTrailingZeros that gives me a good answer, but I don't know how it woorks under the hood, nor how fast it is.
Here is a SSCCE for that method (scavanged from here):
import java.lang.*;
public class IntegerDemo {
public static void main(String[] args) {
int i = 27959296;
System.out.println("Number = " + i);
/* returns the string representation of the unsigned integer value
represented by the argument in binary (base 2) */
System.out.println("Binary = " + Integer.toBinaryString(i));
/* returns the number of zero bits following the lowest-order
("rightmost") one-bit */
System.out.print("Number of trailing zeros = ");
System.out.println(Integer.numberOfTrailingZeros(i));
}
}
What is the fastest method? Am I going the wrong way with bit shifting?
Integer.numberOfTrailingZeros is blazing fast, and i >> Integer.numberOfTrailingZeros(i) is likely to be the fastest alternative possible.

Recursion to get the number of different combinations of n people and k groups

I'm practicing recursion using Java and I've hit a problem. I'm trying to make a method which I'm calling "groups" which takes a number of people and how many groups there are and returns the number of different combinations there are of people and groups. Also, the ordering of people in the groups does not matter, nor does the ordering of the groups.
The code I have so far is:
public long groups(int n, int k) {
if(k==1) return 1;
if(k==n) return 1;
else return groups(n-1, k) + groups(n-1, k-1);
}
However it returns the wrong values. The first two lines are the base cases, which say if there is 1 group, then there is only one way to split the people up, makes sense. The other is when there are just as many people as there are groups, in which case theres only one way to split them up, one person into each group. The last statement is where I think I'm having problems, I would think that each time it does a recursive call, one person has to be taken out (n is the number of people, so n-1) and that person can ether join a group (k) or make their own group (k-1).
I'm just having a little trouble figuring out how recursion works and could use a little help.
These are the values I'm expecting:
groups(2,1) = 1
groups(2,2) = 1
groups(3,2) = 3
groups(4,2) = 7
groups(4,3) = 6
groups(5,3) = 25
There is something missing in the implementation of that part
... and that person can ether join a group (k) ...
I think the person can join 'k' groups, so the code must be
public long groups(int n, int k) {
if(k==1) return 1;
if(k==n) return 1;
else return k * groups(n-1, k) + groups(n-1, k-1);
}
(was missing multiplication by k)
There's a much easier (faster) way to compute combinations -- that's the binomial coefficient. While I can understand that your teacher may want you write a recursive function this way to become familiar with recursion, you can use this formula as a check.
In your case, you're reporting the wrong expected values here. What you want is
groups(2,1) = 2
groups(2,2) = 1
groups(3,2) = 3
groups(4,2) = 6
groups(4,3) = 4
groups(5,3) = 10
and the code you've posted is correct if the values above are what it's supposed to return.
(If not, perhaps you can better clarify the problem by explaining more clearly how the problem you're solving differs from the binomial coefficient.)

Categories