使用递归在Java中找到一个数的底数为2的对数。

huangapple go评论145阅读模式
英文:

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

问题

我正在尝试在Java中编写一个递归方法来找到2的倍数的底数对数。

我已经成功使用这个递归方法计算了对数。

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()
    }
}

在尝试使用不同的方法实现相同程序时,我遇到了困难,这个方法是在递归调用中从2开始相乘,直到它等于给定的数字。这是我尝试过的:

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;
        
    }
}

在第一次调用中,number等于temp,因此我使用了一个step变量来防止执行终止条件。如果我不在递归调用中使用 "number" 变量,我就没有办法累积前一个乘积,但 "number" 变量已经等于 temp 并且将在下一个递归调用中触发终止条件,从而始终输出1。

我该如何修改这个程序以使其工作?

英文:

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?

答案1

得分: 5

第一个版本是固定终止值为1的简化版本。

但第二个版本的终止取决于数字,所以你必须将其传递到递归调用中。因此,你的主函数调用一个私有的递归版本:

    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;
    }

注意:你的算法将值向上取整。要得到(更常见的)向取整的结果,与(int)(Math.log(i) / Math.log(2))一致,可以使用以下变种:

    private static int log(int number, int current) {
        return current <= number / 2 ? log(number, current * 2) + 1 : 0;
    }

这种模式 - 使用包装函数 - 在递归的初始状态需要设置一次的情况下很常见,但我们不希望让调用者知道这是实现选择。


你的第一个方法也可以写成一行:

    static int log(int number) {
        return number == 1 ? 0 : log(number / 2) + 1;
    }   
英文:

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 &lt; 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 &lt;= 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;
}   

答案2

得分: 0

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()
    }
}
英文:

try this:

import java.util.Scanner;

public class LogTest
{
	static int calLog(final int number)
	{
		if(number &lt; 2) {
			return 0;
		}

		return log(number, 2, 1);
	}
	
    static int log(final int number, final int accumulated, final int step)
    {
    	if(accumulated &gt;= 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(&quot;Enter Multiple of 2:&quot;);
        System.out.println(&quot;Log is:&quot;+calLog(input.nextInt())); //calling log with return value of nextInt()
    }
}   

huangapple
  • 本文由 发表于 2020年8月19日 13:00:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63480263.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定