Created
May 19, 2017 19:11
-
-
Save fgoinai/e0410b6b5d207161873526ef66cb8098 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CheckCal { | |
private val MAX = 128 | |
private val valStack = Stack<Int>(MAX) | |
private val opStack = Stack<Char>(MAX) | |
private var buf = CharArray(MAX) | |
fun startCheck(inStream: InputStream) { | |
val reader = inStream.bufferedReader() | |
var prev: Int? = null | |
loop@ while(reader.read(buf) != -1) { | |
t@ for (t in buf) { | |
try { | |
when (t) { | |
' ' -> continue@t | |
'(' -> { | |
opStack.push(t) | |
prev = null | |
} | |
')' -> { | |
closeBracket() | |
prev = null | |
} | |
in nums -> { | |
if(prev!=null) valStack.pop() | |
val intOfT = Character.getNumericValue(t) | |
prev = prev?.times(10)?.plus(intOfT) ?: intOfT | |
valStack.push(prev) | |
} | |
in operators -> { | |
if(!opStack.isEmpty) | |
if(highPriority(t) && opStack.top != '(') | |
operate(opStack.pop()) | |
opStack.push(t) | |
prev = null | |
} | |
'\n' -> { | |
finalCheck() | |
break@loop | |
} | |
else -> close("Only numbers and \"+-*/()\" are accepted!") | |
} | |
} catch (e: Exception) { | |
e.printStackTrace() | |
close("Exceed close brackets!") | |
} | |
} | |
} | |
println("Result is ${valStack.top}") | |
} | |
private fun highPriority(t: Char) = findPriority(opStack.top as Char) < findPriority(t) | |
private fun finalCheck() { | |
while (!opStack.isEmpty && !valStack.isEmpty) { | |
if (valStack.size == 1) throw Exception("Statement Error!") | |
operate(opStack.pop()) | |
} | |
} | |
private fun closeBracket() { | |
for (op in opStack) { | |
if (op == '(') break | |
if (valStack.size < 2) throw Exception("Statement Error!") | |
operate(op) | |
} | |
} | |
private fun operate(tmp: Char) { | |
val cal = calculate(valStack.pop(), valStack.pop()) | |
val ret = when (tmp) { | |
'+' -> cal(Int::plus) | |
'-' -> cal(Int::minus) | |
'*' -> cal(Int::times) | |
'/' -> cal(Int::div) | |
else -> throw Exception("Fuck") | |
} | |
valStack.push(ret) | |
} | |
private fun calculate(arg1: Int, arg2: Int) : ((Int, Int) -> Int) -> Int { | |
return fun (op: (Int, Int) -> Int) : Int { | |
return op(arg2, arg1) | |
} | |
} | |
private fun close(txt: String) { | |
println(txt) | |
System.exit(1) | |
} | |
private val nums = "1234567890".toCharArray() | |
private val operators = "+-*/".toCharArray() | |
val priority = arrayOf( | |
arrayOf('(', ')'), | |
arrayOf('*', '/'), | |
arrayOf('+', '-') | |
) | |
fun findPriority(t: Char) = priority.indexOf(priority.first{it.contains(t)}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment