com.skillw.pouvoir.util.calculate.FormulaParser.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Pouvoir Show documentation
Show all versions of Pouvoir Show documentation
Bukkit Script Engine Plugin.
package com.skillw.pouvoir.util.calculate
import com.skillw.pouvoir.util.calculate.CalcOperator.Companion.isCalcOperator
import com.skillw.pouvoir.util.calculate.CalcOperator.Companion.toCalcOperator
import taboolib.common.platform.function.warning
import java.util.*
private fun String.toCalcInfix(): ArrayList {
//将数字与运算符分开,按中缀表达式顺序排列在List中
val infix = ArrayList()
with(filter { it != ' ' }) {
var begin = 0
forEachIndexed loop@{ index, char ->
if (!char.isCalcOperator()) return@loop
val num = substring(begin, index)
begin = index + 1
if (num.isNotEmpty()) {
infix += num.toDouble()
}
infix += char.toCalcOperator()
}
substring(begin).toDoubleOrNull()?.let {
infix += it
}
}
return infix
}
private fun Stack.nextNotLessThan(calcOperator: CalcOperator): Boolean {
return isNotEmpty() && peek() != CalcOperator.LEFT_BRACKET && peek().priority >= calcOperator.priority
}
/**
* To suffix
*
* @return
*/
private fun List.toCalcSuffix(): Queue {
val suffix = ArrayDeque()
val operators = Stack()
forEach {
if (it is Double) {
suffix.offerLast(it)
return@forEach
}
with(operators) {
when (val calcOperator = it as CalcOperator) {
CalcOperator.LEFT_BRACKET -> push(calcOperator)
CalcOperator.RIGHT_BRACKET -> {
while (isNotEmpty() && peek() != CalcOperator.LEFT_BRACKET) {
suffix.offerLast(pop())
}
if (isNotEmpty())
pop()
}
else -> {
while (nextNotLessThan(calcOperator)) {
suffix.offerLast(pop())
}
push(calcOperator)
}
}
}
}
while (!operators.isEmpty()) {
suffix.offerLast(operators.pop())
}
return suffix
}
private fun Queue.calc(): Double {
val calcStack: Stack = Stack()
while (isNotEmpty()) {
val obj = poll()
if (obj is Double) {
calcStack.push(obj)
continue
}
val calcOperator = obj as CalcOperator
val a = if (calcStack.isEmpty()) 0.0 else calcStack.pop()
val b = if (calcStack.isEmpty()) 0.0 else calcStack.pop()
calcStack.push(calcOperator.calc(a, b))
}
return calcStack.pop()
}
internal fun String.calculateInfix(): Double {
return runCatching {
filter { it != ' ' }.toCalcInfix().toCalcSuffix().calc()
}.getOrElse {
warning("Wrong calculation formula! $this");
0.0
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy