对于一个练习,我必须将Horner函数实现为递归方法,该方法是将任何数字系统转换为Decimal(例如101101²的公式),它是((((((((1·2 + 0) ·2)+ 1)·2)+ 1)·2 + 0)·2 + 1 =45₁₀
现在,该方法获得两个参数,一个数字数组和一个数字系统,例如2个代表二进制。
现在,如果我要使用第三个参数作为“计数器”来遍历数组,那么我将没有问题,但是我无法弄清楚。我可以使用辅助方法,但是我尝试了许多不同的方法,但没有一种有效。也许我在想比实际要复杂的多。有人可以给我小费以引导我朝正确的方向吗? ^^
答案 0 :(得分:0)
我将执行以下操作,其中$ 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;
答案 1 :(得分:0)
我想下面的代码可以满足您的要求:
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.
}
}
如果您在了解step
参数的功能时遇到麻烦,请考虑使其始终等于1!这就是遍历数组的 fast 的方式。例如,值2表示仅考虑半个数字。它可能会使事情复杂一些,但是我创建它的目的是使主要递归方法的方法签名与其他方法不同。通过将step
替换为1,您只能使用最后一个
无论如何,我为每种方法都嵌入了一些javadoc(注释),以帮助您了解我在做什么。主要实现是最后一个 horner 方法。