Java 实现Horner函数递归?
对于一个练习,我必须将Horner函数实现为递归方法,这是一个将任何数字系统转换为十进制的公式,例如101101₂, 它将是(((((()2+0)2+1)2+1)2+0)2+1=45₁₀ 现在该方法得到两个参数,一个数字数组和数字系统,例如二进制的2Java 实现Horner函数递归?,java,algorithm,recursion,Java,Algorithm,Recursion,对于一个练习,我必须将Horner函数实现为递归方法,这是一个将任何数字系统转换为十进制的公式,例如101101₂, 它将是(((((()2+0)2+1)2+1)2+0)2+1=45₁₀ 现在该方法得到两个参数,一个数字数组和数字系统,例如二进制的2 现在,如果我有第三个参数,它将作为一个“计数器”来遍历数组,我不会有任何问题,但我就是搞不清楚。我被允许使用helper方法,但我尝试了许多不同的方法,但都没有成功。也许我想的比实际情况更复杂。有人能给我一个提示,引导我走向正确的方向吗 我将执行
现在,如果我有第三个参数,它将作为一个“计数器”来遍历数组,我不会有任何问题,但我就是搞不清楚。我被允许使用helper方法,但我尝试了许多不同的方法,但都没有成功。也许我想的比实际情况更复杂。有人能给我一个提示,引导我走向正确的方向吗 我将执行以下操作,$a是包含数字的字符串,$b是系统
$multiplier = (int)$b;
$result = 0;
while (len($a) > 1) {
$digit = (int)substr($a, -1);
$result += $digit * $multiplier;
$a = substr($a, 0, -1);
$multiplier = $multiplier * $b;
}
$result += ((int)$a) * $multiplier;
我认为以下代码符合您的要求:
public class Main {
/**
* Hepler method to convert codepoints ('digitCodePoints') into their decimal corresponding
* number (to be used with {@link #horner(java.lang.String, java.lang.String) horner method})
* depending on the alphabet ('alphabetCodePoints').
* @param digitCodePoints the raw digits of the number (most significant digit first).
* @param alphabetCodePoints the raw alphabet codepoints of the system (least significant codepoint first). For example "01" for binary.
* @return
*/
private static int[] toDigits(final int[] digitCodePoints,
final int[] alphabetCodePoints) {
final int[] result = new int[digitCodePoints.length];
for (int d = 0; d < digitCodePoints.length; ++d) {
//Find where is the digitCodePoints[d] located in alphabetCodePoints:
int index = 0;
while (digitCodePoints[d] != alphabetCodePoints[index]) //Will throw ArrayIndexOutOfBoundsException if the digitCodePoints[d] is not found in alphabetCodePoints.
++index;
result[d] = index;
}
return result;
}
/**
* Works on codepoints.
* @param digits the codepoints' literal which stores the digits of the number.
* @param alphabet the alphabet of the system for which the convertion will take place. For example "01" for binary. Least significant digit comes first.
* @return the decimal value of the resulting number.
*/
public static int horner(final String digits,
final String alphabet) {
final int[] alphabetCPs = alphabet.codePoints().toArray();
return horner(toDigits(digits.codePoints().toArray(), alphabetCPs), alphabetCPs.length);
}
public static int horner(final int[] digits,
final int system) {
return horner(digits, 0, digits.length, system);
}
/**
* Standard method for converting 'digits' to their decimal number by Horner's method.
* @param digits the digits of each place (most significant digit first).
* @param offset the offset of 'digits' where we should end recursing.
* @param length the length of 'digits' starting at 'offset'.
* @param system the system for the convertion. For example 2 for binary, 16 for hexadecimal, and so on.
* @return the decimal value of the resulting number.
*/
public static int horner(final int[] digits,
final int offset,
final int length,
final int system) {
return horner(digits, offset, offset + length - 1, 1, system);
}
/**
* Main recursive method.
* @param digits the digits of each place (most significant digit first).
* @param offset the offset of 'digits' where we should end recursing.
* @param index the index in digits to calculate next.
* @param step how 'fast' we are traversing the array 'digits'. Typically 1. This exists mainly to create a different method signature than {@link #horner(int[], int, int, int) this} method.
* @param system the system for the convertion. For example 2 for binary, 16 for hexadecimal, and so on.
* @return the decimal value of the resulting number.
*/
private static int horner(final int[] digits,
final int offset,
final int index,
final int step,
final int system) {
if (digits[index] >= system)
throw new IllegalArgumentException("digits[" + index + "]==" + digits[index] + " does not belong to the system " + system + '.');
return index - step < offset
? digits[index]
: horner(digits, offset, /* here you can see the usage of 'step': */ index - step, step, system) * system + digits[index];
}
public static void main(final String[] args) {
System.out.println(horner( new int[]{1, 0, 1, 1} , 2 )); //11.
System.out.println(horner( new int[]{0xF, 0xF} , 16 )); //255.
System.out.println(horner( /* the number: */ "ffff" , /* the alphabet: */ "0123456789abcdef" )); //65535.
}
}
公共类主{
/**
*Hepler方法将代码点(“digitCodePoints”)转换为对应的十进制数
*编号(与{@link#horner(java.lang.String,java.lang.String)horner方法}一起使用)
*取决于字母表(“alphabetCodePoints”)。
*@param DigitCode指向数字的原始数字(最重要的数字在前)。
*@param alphabetCodePoints系统的原始字母代码点(首先是最低有效代码点)。例如,“01”表示二进制。
*@返回
*/
私有静态int[]到数字(最终int[]数字代码点,
最终整数[]字母betcodepoints){
最终int[]结果=新int[digitCodePoints.length];
对于(int d=0;d=系统)
抛出新的IllegalArgumentException(“digits[“+index+”]”]=“+digits[index]+”不属于系统“+system+”);
返回索引-步长<偏移量
?数字[索引]
:horner(数字,偏移量,/*这里您可以看到'step'的用法:*/index-step,step,system)*system+数字[index];
}
公共静态void main(最终字符串[]args){
System.out.println(horner(newint[]{1,0,1,1},2));//11。
System.out.println(horner(新的int[]{0xF,0xF},16));//255。
System.out.println(horner(/*数字://“ffff”,字母://“0123456789abcdef”);///65535。
}
}
如果你在理解<代码>步骤< /代码>参数时有困难,考虑它总是等于1!这是遍历数组的速度。例如,值2表示只考虑半位数。它可能会使事情复杂一些,但我创建它是为了使主递归方法的方法签名与其他方法不同。您只能使用最后一个horner方法,将
步骤
替换为1
无论如何,我已经为每个方法嵌入了一些javadoc(注释),以帮助您理解我在做什么。主要的实现是最后一个horner方法。谢谢你的回答,但问题是我需要递归地执行它,并且使用数字数组作为参数:/(一种方法