我一直在運行一種演算法,該演算法旨在采用后綴運算式并回傳評估值。
為了執行各個功能,我設計了一個串列陣列,它們的功能基本上是:
操作的字串表示形式:字串,取值(-1):整數,描述要做什么的函式:浮點數 我把它寫成
val functions = arrayOf<List<Any>>(
listOf(" ",1,fun (i:List<Float>):Float = i[0] i[1]),
listOf("-",1,fun (i:List<Float>):Float = i[0] - i[1]),
// etc (rest of them are currently commented out)
)
在編譯這個我得到了錯誤:
app\src\main\kotlin\KotlinApp.kt: (48, 34): Expression 'f[2]' of type 'Any' cnvoked as a function. The function 'invoke()' is not found
這是指我如何呼叫陣列f[2](temp:List<Float>)的元素f。
我認識到這里的錯誤是因為我的串列是 type any,所以其中的函式不被編譯器假定為函式。但是由于我顯然不能將這些轉換為函式,所以我很茫然。
我嘗試使用 lambda 運算式而不是匿名單運算式函式,即
val functions = arrayOf<List<Any>>(
listOf(" ",1,i : List<Float> -> i[0] i[1],
listOf("-",1,i : List<Float> -> i[0] - i[1]),
// etc
)
但是由于我對 lambdas 不是特別熟悉,所以我不知道我是否做得正確。
任何幫助,將不勝感激
完整的 KotlinApp.kt 檔案:
package gradleMain;
import org.shuntingyard.sya
import kotlin.math.*
import java.util.Stack
class KotlinApp {
val functions = arrayOf<List<Any>>(
listOf(" ",1,fun (i:List<Float>):Float = i[0] i[1]),
listOf("-",1,fun (i:List<Float>):Float = i[0] - i[1]),
// listOf("*",1,{ i : List<Float> -> i[0]*i[1]}),
// listOf("/",1,{ i : List<Float> -> i[0]/i[1]}),
// listOf("^",1,{ i : List<Float> -> i[0].pow(i[1])}),
// listOf("sin",0,{ i : List<Float> -> sin(i[0])}),
// listOf("cos",0,{ i : List<Float> -> cos(i[0])}),
// listOf("tan",0,{ i : List<Float> -> tan(i[0])}),
// listOf("asin",0,{ i : List<Float> -> asin(i[0])}),
// listOf("acos",0,{ i : List<Float> -> acos(i[0])}),
// listOf("atan",0,{ i : List<Float> -> atan(i[0])}),
// listOf("sinh",0,{ i : List<Float> -> sinh(i[0])}),
// listOf("cosh",0,{ i : List<Float> -> cosh(i[0])}),
// listOf("tanh",0,{ i : List<Float> -> tanh(i[0])}),
// listOf("fact",0, /* TODO: Need to incorporate gamma function, once established integrals" */ ),
// listOf("int",1,/* TODO: Incorporate integrals */),
// listOf("dif",1,/* TODO: Incorporate differentiation */),
// listOf("log",0,{ i : List<Float> -> log(i[0], 10F)}),
// listOf("ln",0,{ i : List<Float> -> ln(i[0])}),
// listOf("sqrt",0,{ i : List<Float> -> i[0].pow(0.5F)}),
// listOf("sec",0,{ i : List<Float> -> 1/cos(i[0])}),
// listOf("csc",0,{ i : List<Float> -> 1/sin(i[0])}),
// listOf("cot",0,{ i : List<Float> -> 1/tan(i[0])})
)
fun calculate(eq:List<String>):Float{ // takes the rpn of the equation and returns the result
var operand: Stack<String> = Stack()
var temp = listOf<Float>()
for(i in eq){
var n = false
for(f in functions){
if(i==f[0]){
val x: Int = f[1].toString().toInt()
for(j in 0..x){
temp =operand.pop().toFloat()
}
operand.push(f[2](temp))
n = true
break;
}
}
if(!n){ // when i isnt an operator/function
operand.push(i)
}
}
val result = operand.peek().toFloat()
return result
}
}
fun main(){
val k = KotlinApp()
val e = sya(" 3 7 - 2") // runs shunting yard algorithm on equation
val f = k.calculate(e)
println("$f")
}
uj5u.com熱心網友回復:
注意:我沒有看你的邏輯。幫助解決您訪問功能的問題。所以這就是事情。
- 您可以使用Triple物件代替 List 的串列,這將有助于保存變數的型別。由于內部串列中只有三個專案,所以 Triple 可能適合您。因為您擁有多種型別的內部串列。所以你可以做 typecasting ,但不推薦。
- 您可以使用TypeAlias定義函式型別以獲得更好的可讀性。
計算函式:
fun calculate(eq:List<String>):Float{ // takes the rpn of the equation and returns the result
var operand: Stack<String> = Stack()
val temp = mutableListOf<Float>()
for (i in eq){
var n = false
for (f in functions){
if (i == f.first){
val x: Int = f.second.toString().toInt()
for(j in 0..x){
temp =operand.pop().toFloat()
}
operand.push(f.third(temp).toString()) // Float to String
n = true
break
}
}
if(!n){ // when i isnt an operator/function
operand.push(i)
}
}
val result = operand.peek().toFloat()
return result
}
函式的自定義型別:
typealias MyFunctionType = (a:List<Float>) -> Float
功能串列:
val functions = arrayListOf<Triple<String,Int,MyFunctionType>>(
Triple(" ",1,fun (i:List<Float>):Float = i[0] i[1]),
Triple("-",1,fun (i:List<Float>):Float = i[0] i[1])
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/509875.html
標籤:科特林毕业典礼
下一篇:為什么kotlin-gradle-plugin無法從CodeInsightTestFixture.configureByText創建PSIFile?
