我正在嘗試將L 系統實作為函式。例如,龍曲線如下所示:
static String F(int n) {
return n == 0 ? "F" : F(n - 1) " " G(n -1);
}
static String G(int n) {
return n == 0 ? "G" : F(n - 1) "-" G(n -1);
}
@Test
void testDragonCurveAsStaticFunction() {
assertEquals("F", F(0));
assertEquals("F G", F(1));
assertEquals("F G F-G", F(2));
assertEquals("F G F-G F G-F-G", F(3));
}
我想用 lambda 函式來實作這個。我通過參考遞回得到以下實作- 使用 Java 8 實作遞回 lambda 函式 - 堆疊記憶體溢位。
@Test
void testDragonCurveAsLambdaFunction() {
interface IntStr { String apply(int i); }
IntStr[] f = new IntStr[2];
f[0] = n -> n == 0 ? "F" : f[0].apply(n - 1) " " f[1].apply(n - 1);
f[1] = n -> n == 0 ? "G" : f[0].apply(n - 1) "-" f[1].apply(n - 1);
assertEquals("F", f[0].apply(0));
assertEquals("F G", f[0].apply(1));
assertEquals("F G F-G", f[0].apply(2));
assertEquals("F G F-G F G-F-G", f[0].apply(3));
}
有沒有辦法在不使用陣列的情況下實作這一點?
但是我想創建一個通用的L-System,所以我不想為龍曲線定義一個新的類、介面或方法。
uj5u.com熱心網友回復:
我嘗試使用一個類來實作它,該類結合了IntStr通過建構式或 setter 設定的兩個欄位:
interface IntStr {
String apply(Integer i);
}
class Recursive {
IntStr other;
IntStr curr;
public Recursive() {}
public Recursive(String p1, String s1, String p2, String s2) {
this.curr = n -> n == 0 ? p1 : curr.apply(n - 1) s1 other.apply(n - 1);
this.other = n -> n == 0 ? p2 : curr.apply(n - 1) s2 other.apply(n - 1);
}
public void setCurr(String p, String s) {
this.curr = n -> n == 0 ? p : curr.apply(n - 1) s other.apply(n - 1);
}
public void setOther(String p, String s) {
this.other = n -> n == 0 ? p : curr.apply(n - 1) s other.apply(n - 1);
}
}
然后下面的代碼成功了:
void testDragonCurveAsLambdaFunction() {
Recursive f1 = new Recursive("F", " ", "G", "-");
// or using setters
// f1.setCurr("F", " ");
// f1.setOther("G", "-");
assertEquals("F", f1.curr.apply(0));
assertEquals("F G", f1.curr.apply(1));
assertEquals("F G F-G", f1.curr.apply(2));
assertEquals("F G F-G F G-F-G", f1.curr.apply(3));
}
一個不創建類AtomicReference作為容器IntStr參考的例子Recursive:
void testDragonCurveAsLambdaFunction() {
AtomicReference<IntStr>
curr = new AtomicReference<>(),
other = new AtomicReference<>();
curr.set(n -> n == 0 ? "F" : curr.get().apply(n - 1) " " other.get().apply(n - 1));
other.set(n -> n == 0 ? "G" : curr.get().apply(n - 1) "-" other.get().apply(n - 1));
assertEquals("F", curr.get().apply(0));
assertEquals("F G", curr.get().apply(1));
assertEquals("F G F-G", curr.get().apply(2));
assertEquals("F G F-G F G-F-G", curr.get().apply(3));
}
uj5u.com熱心網友回復:
我找到了一個使用 Map 的解決方案。
@FunctionalInterface
interface IntStr {
String apply(int n);
static IntStr cond(String then, IntStr... otherwise) {
return n -> n == 0 ? then
: Stream.of(otherwise)
.map(f -> f.apply(n - 1))
.collect(Collectors.joining());
}
static IntStr constant(String string) {
return n -> string;
}
static IntStr call(Map<String, IntStr> map, String functionName) {
return n -> map.get(functionName).apply(n);
}
}
和
@Test
void testDragonCurveAsLambda() {
Map<String, IntStr> map = new HashMap<>();
map.put("F", IntStr.cond("F",
IntStr.call(map, "F"),
IntStr.constant(" "),
IntStr.call(map, "G")));
map.put("G", IntStr.cond("G",
IntStr.call(map, "F"),
IntStr.constant("-"),
IntStr.call(map, "G")));
IntStr f = map.get("F");
assertEquals("F", f.apply(0));
assertEquals("F G", f.apply(1));
assertEquals("F G F-G", f.apply(2));
assertEquals("F G F-G F G-F-G", f.apply(3));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/384452.html
