Finding the Base 2 Logarithm of a number using Recursion in java - java

I'm trying to write a recursive method in Java to find the base 2 log for multiples of 2.
I've successfully computed the log using this recursive method.
import java.util.*;
class temp
{
static int log(int number)
{
if(number==1)
return 0;
return log(number/2)+1;
}
public static void main(String s[])
{
Scanner input=new Scanner(System.in);
System.out.println("Enter Multiple of 2:");
System.out.println("Log is:"+log(input.nextInt())); //calling log with return value of nextInt()
}
}
Where I've run aground is trying to implement the same program using a different method , a method where i start multiplying from 2 in recursive calls until it becomes equal to the given number. Here's what i've tried:
class logarithmrecursion
{
static int step=1;
static int log(int number)
{
final int temp=number;
if(number>=temp && step!=1)
return 0;
step++;
return log(number*2)+1;
}
}
During the first call, number is equal to temp so i use a step variable to prevent the execution of the termination condition.If i don't use "number" variable in the recursive call, i don't have a way to accumulate the previous product but number variable is already equal to temp and will trigger the termination condition in the next recursive call , thus always giving output 1.
What can i do to make this program work?

The first, reducing, version has a fixed termination value of 1.
But the second version's termination depends on the number, so you have to pass that into the recursive call. So, your main function calls a private recursive version:
static int log(int number) {
return log(number, 1);
}
private static int log(int number, int current) {
return current < number ? log(number, current * 2) + 1 : 0;
}
Note: Your algorithm rounds the value up. To give the (more expected) rounded down result, which agrees with (int)(Math.log(i) / Math.log(2)), use this variation:
private static int log(int number, int current) {
return current <= number / 2 ? log(number, current * 2) + 1 : 0;
}
This kind of pattern - using a wrapper function - is common where initial state of the recursion needs to setup once, but we don't want to burden the caller with having to know about what is an implementation choice.
Your first method may also be coded as one line:
static int log(int number) {
return number == 1 ? 0 log(number/2) + 1;
}

try this:
import java.util.Scanner;
public class LogTest
{
static int calLog(final int number)
{
if(number < 2) {
return 0;
}
return log(number, 2, 1);
}
static int log(final int number, final int accumulated, final int step)
{
if(accumulated >= number) {
return step;
}
return log(number, accumulated * 2, step+1);
}
public static void main(String s[])
{
Scanner input=new Scanner(System.in);
System.out.println("Enter Multiple of 2:");
System.out.println("Log is:"+calLog(input.nextInt())); //calling log with return value of nextInt()
}
}

Related

Java: Having trouble finding the minimum value of a Queue?

I'm using arraylist to implement a queue. Everything is going good except when I try to find the minimum value of the queue it does not work properly and the dequeue and peek functions for some reason do not work as expected. I tried going through line by line but I don't understand what is going wrong in the min() function:
public class queuePractice {
static ArrayList<Integer>nums = new ArrayList<Integer>();
static int top = -1;
public static void main(String[] args) {
enqueue(5);
enqueue(2);
enqueue(6);
enqueue(3);
enqueue(12);
enqueue(1);
enqueue(20);
System.out.println("The min is: " + min());
}
public static int peek() {
return nums.get(0);
}
public static void enqueue(int x) {
nums.add(++top, x);
}
public static int dequeue() {
top--;
return nums.remove(0);
}
public static void display() {
for(int x = 0; x <=top; x++) {
System.out.print(nums.get(x) + " ");
}
System.out.println();
}
public static boolean isEmpty() {
return top==-1;
}
public static int min() {
int min = Integer.MAX_VALUE;
while(min > peek()) {
min = peek();
dequeue();
}
return min;
}
}
The peek function keeps returning 2 over and over, even if I change the while loop to a for loop. For some reason it is not updating its value whenever I dequeue it? But going through line by line I can't understand what's wrong.
An easier method would be
List<Integer>nums = Arrays.asList(5,2,35,6); // or use your enqueue
Iterator<Integer> it = nums.iterator();
int min = Integer.MAX_VALUE;
while (it.hasNext()) {
Integer i = it.next();
min = Math.min(i, min);
}
System.out.println(min);
Of course any type of looping around the List would work
Did you mean your code is printing 2 all the time? That's because your min() method always terminate on 2
First iteration your int min value will be 5
Second iteration your int min value will be 2
Third iteration your loop will exit since 2 is not bigger than 6
Then your method will return 2
hope it helps

Need to call scanner method read.nextInt() twice but want the same value for both

At the moment I'm calling the method reader.nextInt() twice so it's only using the addNumber() method for every other value rather than each one.
How do I go about fixing this issue?
I've tried using a while loop containing (true) as well as the one printed below, both encounter the same issue.
I forgot to mention, I need the programme to print the sum of all integers entered. This is to be triggered by entering the value of -1. The -1 is meant to be excluded from the sum.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
NumberStatistics stats = new NumberStatistics();
Scanner reader = new Scanner (System.in);
System.out.println("Type numbers:");
while (reader.nextInt() != -1) {
stats.addNumber(reader.nextInt());
}
System.out.println("sum: " + stats.sum());
}
}
public class NumberStatistics {
private int amountOfNumbers;
private int sum;
public NumberStatistics() {
amountOfNumbers = 0;
sum = 0;
}
public void addNumber(int number) {
this.amountOfNumbers++;
this.sum += number;
}
public int amountOfNumbers() {
return this.amountOfNumbers;
}
public int sum() {
return this.sum;
}
public double average() {
if (this.sum() == 0) {
return 0;
}
else {
return (double) this.sum / this.amountOfNumbers;
}
}
}
You are calling twice nextInt(), hence reading two nubers one after the other.
You can do what you want like this:
int num;
while ((num = reader.nextInt()) != -1) {
stats.addNumber(num);
}
This makes use of the fact that assignment expressions (this: num = reader.nextInt()) not only assigns the value to num, but aslo evaluate to the value being assigned, so that we can compare it with -1.
The problem here is that the scanner will jump to the next token for each call of nexInt() that's why you get the following numbers, and skip the expected one.
So don't use nextInt() in your while condition, use hasNextInt() instead.
So your code would look like this:
int next;
while (reader.hasNextInt() && (next = reader.nextInt()) != -1){
stats.addNumber(next);
}
When you call nextInt(), the pointer in the scanner parse the int, then goes to the next element. So basically, you have :
pointer
|
|
12345 12346 12347
while (nextInt() ...) // pointer moves to next int
pointer
|
|
12345 12346 12347
stats.addNumber(reader.nextInt()); // Now the pointer is already at the next one
So you are reading them two by two. You can correct this by doing:
int a;
while ((a = reader.nextInt()) != -1)
stats.addNumber(a);
This way, the Reader#nextInt method is only called once.

Create method that prints the numbers between two specified numbers

So I'm creating a method in that is supposed to print the numbers between two specified numbers. I had it setup before in the main method but i can figure out how to make a method and call it into the main method. What my program does right now is it only prints what "int between" is equal to. I don't want anyone to just type the code out for me, i'm just looking for tips on what i should change. Last time i asked a question someone proceeded to just answer with code and it did not help me to learn anything.
So my question is what is causing the program to only display what between is equal to? I know that I need a value for the if loop to return something, but it needs to return the numbers between num1 & num2. My Professor Also said that the method needs to be "public static void Printer(int num1, int num2)" is that even possible? I kept getting an error so I switched to "int Printer".
package nortonaw_Assignment8;
public class Nortonaw_Assignment8 {
public static void main(String[] args) {
int between;
between = Printer(5, 20);
System.out.println(between);
}
public static int Printer (int num1, int num2){
int between = 0;
for (;num1<=num2; num1++);
return between;
}
}
1) There's a difference between printing out a value and returning a value.
When you"print" a value in a function, you are just writing out the value to screen or some other medium , but when you use the return statement, you are passing what you are returning to the caller of your function as well as control.
** I hope that makes sense to you?
2)"public static void Printer(int num1, int num2)" is possible.
currently your method is designed to return only one single number, so either you return a collection of numbers are you print the numbers inside Printer, in this case you can use the method signature suggested by your professor.
So I would write it like this:
public static void main(String[] args) {
Printer(5, 20);
}
public static void Printer (int num1, int num2) {
for (int i=num1;i<=num2; i++) {
System.out.println(i);
}
}
EDIT:
Note that I introduced a additional counter variable i because I think num1 and num2 should not be changed as they define the boundary of your range.
package printingTasks;
public class Printer {
public static void main(String[] args) {
printInBetween(25, 30); //Would print 26 -> 29
}
/*
* You don't need to return something if you just want to print it out to the console.
* So you can use void as return type
*/
public static void printInBetween(final int leftBoundary, final int rightBoundary){
/**
* Calculate the first number which should be printed.
* This number would be the leftBoundery plus one
* This number will be the starting point of your loop
*/
final int firstNumber = leftBoundary + 1;
// final int firstNumber = leftBoundary; //if you want to include the left boundary
for (
int currentNumber = firstNumber; //Set the counter of the the loop (currentNumber) to the first valid number
currentNumber < rightBoundary; //Run the loop while the loop counter is less than the rightBoundary
// currentNumber <= rightBoundary; //If you want to include the right boundary
currentNumber++ //Increment the loop counter with each iteration
){
/**
* In each iteration you will print the current value of the counter to the console
* Because your counter (currentNumber) will be incremented from the first valid number
* to the last number before the right boundary you will get all numbers between the two
* boundaries.
*/
System.out.println(currentNumber);
}
}
}
Your teacher wants you to print from the Printer method not directly in the main method. All the main method should be doing is calling the Printer method.
Here is the full snippit:
package nortonaw_Assignment8;
public class Nortonaw_Assignment8 {
public static void main(String[] args) {
Printer(5, 20);
}
public static void Printer (int num1, int num2) {
for (int i = num1+1;i<=num2-1; i++) {
System.out.println(i);
}
}
}

Sum of Numbers Recursion

I want to display every number leading up to the variable 'number'.
Example, if the number is 5, I would want the result to be 1 2 3 4 5. I have an error for returning a value, I'm not sure why. How do I return the results using recursion?
public class SumOfNumbers {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.println("Number?");
int number = keyboard.nextInt();
System.out.println(recursion(number));
}
public static int recursion(int number)
{
for (int i=0;i>number;i++)
{
return recursion(i);
}
else {
return number ;
}
}
}
You are mixing recursion and iteration. The for loop is unnecessary in your recursive solution.
Think of your recursive solution as if it already exists: what would you do if a program "print numbers up to n-1" was given to you, and you were asked to write a program that prints numbers up to n? The solution would be pretty clear - you would write it like this:
void myRecursiveProgram(int n) {
if (n == 0) {
return; // do nothing
}
printNumbersUpToN(n-1); // Go up to n-1 using the "magic solution"
System.out.println(n); // Complete the task by printing the last number
}
Now observe that myRecursiveProgram is your printNumbersUpToN program, so all you need to do is renaming it:
void printNumbersUpToN(int n) {
if (n == 0) {
return; // do nothing
}
printNumbersUpToN(n-1);
System.out.println(n);
}
Note the if (n == 0) step: it's very important, because it prevents your recursion from going non-stop into negative territory. This is called the base case of recursion - i.e. the case when you do a fixed amount of work, or no work at all.
Your code doesn't compile, you have an else without if.
What you are trying to do is something like:
import java.util.Scanner;
public class SumOfNumbers {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.println("Number?");
int number = keyboard.nextInt();
recursion(number);
}
public static void recursion(int number)
{
if (number>1)
{
recursion(number-1);
System.out.print(number);
}
else {
System.out.print(number);
}
}
}
This short code will also print the numbers right.
public void recursion(int number){
if (number>1)
recursion(number-1);
System.out.println(number);
}

Recursion: Binary to Decimal

I am working on a recursive method that takes a binary number as a string and displays its decimal equivalent. I am unsure if my base cases are correct. Also, am I properly imposing recursion within the method?
public static void main(String[] args){
System.out.println("Enter a binary string ");
String binary = input.nextLine();
System.out.println("The decimal equivalent of " + binary + " is "+ binary2Decimal(binary));
}
//MethodOverloading
public static int binary2Decimal(String binary){
return binary2Decimal(binary,0, binary.length()-1);
}
public static void binary2Decimal(String binary, int low, int high){
int temp=0;
if(binary.charAt(high) == 0)
temp *= 2;
else if(binary.charAt(high) == 1)
temp = (temp * 2) + 1;
return binary2Decimal(binary,low,high -1)+temp;
}
}
You don't have a base case; binary2Decimal (3-arg version) always calls itself. (Since the only thing changing from one call to the next is high, your base case should probably involve that somehow.)
Some points:
Your method:
public static void binary2Decimal(String binary, int low, int high)
should have a return type of int instead of void.
You aren't using your variable low (so you can get rid of it if you want).
You need a base case with some code like:
if (high == 0) {
return somevalue;
}
else {
return binary2Decimal(binary,low,high -1)+temp;
}
Otherwise you will get into an infinite loop, and your method will recurse indefinitely.

Categories

Resources