私が達成しようとしている背景/目標:
私は(練習として)最初からJavaでの高速累乗アルゴリズムを実装しようとしています。(johndcook.comから採取説明)以下のようなアルゴリズムです。
入力:ベースB、指数N。
バイナリでの指数nを書きます。左から2番目のビットで開始し、左から右にバイナリ表現を読み取ります。数aでスタートし、あなたが0ビット、あなたが持っているものの正方形を読むたびに。たびに、あなたは1ビット、あなたが得たと乗算することによってした内容の正方形をお読みください。それには2つ以上のlog2(N)回の乗算を使用しない計算することができることになります。
私は、このアルゴリズムを実装するためのより良い方法を捜しているわけではないのではなく、なぜ私は、この特定のエラーを取得しています。
どのような問題があります
私はJavaで再帰的なラムダを使用して、このアルゴリズムを実装しようとした、と私はプログラムを実行するために行ったとき、私は次のエラーを得ました:
Main.java:11:エラー:シンボルを見つけることができません
exponentiator = (int runningResult, int binLength, int binInt, int expBase) -> { ^
Main.java:11:エラー:ここでは期待できないラムダ式
exponentiator = (int runningResult, int binLength, int binInt, int expBase) -> { ^
Main.java:23:エラー:シンボルを見つけることができません
exponentiator(b, length, nBinInt, b); ^
私はこれらのエラーの説明、缶誰の助け私何を持っていませんか?
コード:
class Main {
public static void main(String[] args) {
fastExp(2, 13);
}
//This is the algorithm itself
public static int fastExp(int b, int n) {
//converts n (b^n) to binary for algorithm
String nBinStr = Integer.toBinaryString(n);
int nBinInt = Integer.parseInt(nBinStr);
int length = String.valueOf(nBinInt).length();
exponentiator = (int runningResult, int binLength, int binInt, int expBase) -> {
int firstDigit = Integer.parseInt(Integer.toString(binInt).substring(1, 2));
if(binLength = 0){
return runningResult;
}
else if(firstDigit = 0){
exponentiator((runningResult * runningResult), (binLength - 1), (binInt % (int) Math.pow(10, (int) Math.log10(binInt))), expBase);
}
else {
exponentiator((runningResult * runningResult * base), (binLength - 1), (binInt % (int) Math.pow(10, (int) Math.log10(binInt))), expBase);
}
};
exponentiator(b, length, nBinInt, b);
}
}
あなたが持っている大きな問題の1つは、あなたのラムダが型を持っていないということです。あなたはそれを1つずつ与える必要があります。私は、のいずれかの種類を認識していないよjava.util.function
あなたは、おそらくこのタイプを自分で宣言する必要があるので、4つのパラメータを取る機能を表現することができます。
他の主要な問題は、変数を使用していることでexponentiator
無効であるその宣言、内。この問題を回避するには、ラムダ自体が渡される先のあなたのラムダに5番目のパラメータを追加する必要があります。あなたは、このパラメータへの呼び出しで再帰呼び出しに置き換えられます。
レッツは、最初にこのラムダを表現する型を宣言します。
interface IntQuadRecursiveFunction {
int apply(int a, int b, int c, int d, IntQuadRecursiveFunction f);
}
そして、exponentiator
そのように再宣言することができます。
// note the type and extra parameter "f"
IntQuadRecursiveFunction exponentiator = (runningResult, binLength, binInt, expBase, f) -> {
int firstDigit = Integer.parseInt(Integer.toString(binInt).substring(1, 2));
if (binLength == 0) { // It's "==", not "="
return runningResult;
} else if (firstDigit == 0) {
// note the word "return", which you were missing
// also the extra argument "f"
return f.apply((runningResult * runningResult), (binLength - 1), (binInt % (int) Math.pow(10, (int) Math.log10(binInt))), expBase, f);
} else {
// should be "expBase", not "base"
return f.apply((runningResult * runningResult * expBase), (binLength - 1), (binInt % (int) Math.pow(10, (int) Math.log10(binInt))), expBase, f);
}
};
使用法:
// you are missing a return in "fastExp" as well
return exponentiator.apply(b, length, nBinInt, b, exponentiator); // note the last argument
私があなただったら正直に言うと、私はこのすべてのトラブルを保存し、代わりに通常の方法を記述します。
public static int fastExp(int b, int n) {
//converts n (b^n) to binary for algorithm
String nBinStr = Integer.toBinaryString(n);
int nBinInt = Integer.parseInt(nBinStr);
int length = String.valueOf(nBinInt).length();
return exponentiator(b, length, nBinInt, b);
}
private static int exponentiator(int runningResult, int binLength, int binInt, int expBase) {
int firstDigit = Integer.parseInt(Integer.toString(binInt).substring(1, 2));
if (binLength == 0) {
return runningResult;
} else if (firstDigit == 0) {
return exponentiator((runningResult * runningResult), (binLength - 1), (binInt % (int) Math.pow(10, (int) Math.log10(binInt))), expBase);
} else {
return exponentiator((runningResult * runningResult * expBase), (binLength - 1), (binInt % (int) Math.pow(10, (int) Math.log10(binInt))), expBase);
}
}