I want to write code in dart that can calculate like this expression: 100 * ( 2 + 12 ) / 14 (infix notation) taking into consideration the priority of operators. for ex: "*" is stronger than "+". The code below fixes my issue but it's written in JavaScript, I tried to convert it to dart but I am stuck.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Infix Notation</title>
</head>
<body>
<script>
function evaluate(expression){
let tokens = expression.split(' ');
// Stack for numbers: 'values'
let values = [];
// Stack for Operators: 'ops'
let ops = [];
for (let i = 0; i < tokens.length; i++){
if (tokens[i] >= '0' && tokens[i] <= '9'){
let number = "";
// There may be more than one digits in number
while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9'){
number = number + tokens[i++];
}
document.write(number + "</br>");
values.push(parseInt(number, 10));
// Right now the i points to
// the character next to the digit,
// since the for loop also increases
// the i, we would skip one
// token position; we need to
// decrease the value of i by 1 to
// correct the offset.
i--;
}
// Current token is an opening
// brace, push it to 'ops'
else if (tokens[i] == '(')
{
ops.push(tokens[i]);
}
// Closing brace encountered,
// solve entire brace
else if (tokens[i] == ')')
{
while (ops[ops.length - 1] != '(')
{
values.push(applyOp(ops.pop(),
values.pop(),
values.pop()));
}
ops.pop();
}
// Current token is an operator.
else if (tokens[i] == '+' ||
tokens[i] == '-' ||
tokens[i] == '*' ||
tokens[i] == '/')
{
// While top of 'ops' has same
// or greater precedence to current
// token, which is an operator.
// Apply operator on top of 'ops'
// to top two elements in values stack
while (ops.length > 0 &&
hasPrecedence(tokens[i],
ops[ops.length - 1]))
{
values.push(applyOp(ops.pop(),
values.pop(),
values.pop()));
}
// Push current token to 'ops'.
ops.push(tokens[i]);
}
}
// Entire expression has been
// parsed at this point, apply remaining
// ops to remaining values
while (ops.length > 0){
values.push(applyOp(ops.pop(),
values.pop(),
values.pop()));
}
// Top of 'values' contains
// result, return it
return values.pop();
}
// Returns true if 'op2' has
// higher or same precedence as 'op1',
// otherwise returns false.
function hasPrecedence(op1, op2){
if (op2 == '(' || op2 == ')')
{
return false;
}
if ((op1 == '*' || op1 == '/') &&
(op2 == '+' || op2 == '-'))
{
return false;
}
else
{
return true;
}
}
// A utility method to apply an
// operator 'op' on operands 'a'
// and 'b'. Return the result.
function applyOp(op, b, a){
switch (op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
{
document.write("Cannot divide by zero");
}
return parseInt(a / b, 10);
}
return 0;
}
document.write(evaluate("10,5 + 2 * 6") + "</br>");
document.write(evaluate("100 * 2 + 12") + "</br>");
document.write(evaluate("100 * ( 2 + 12 )") + "</br>");
document.write(evaluate( "100 * ( 2 + 12 ) / 14") + "</br>");
// This code is contributed by decode2207.
</script>
</body>
</html>
In dart there is no built in function for stack so we have to write its class in order to use push(), pop(), length.. as below:
class Values<T> {
final _list = <T>[];
void push(T value) => _list.add(value);
T pop() => _list.removeLast();
T get top => _list.last;
bool get isEmpty => _list.isEmpty;
bool get isNotEmpty => _list.isNotEmpty;
int get length => _list.length;
T get peek => _list.last;
@override
String toString() => _list.toString();
}
Arraywith conveniencepush/popmethods. You can just use a DartListdirectly as a stack in the same way usingaddinstead ofpush,removeLastinstead ofpopandlastinstead oftop/peek, without needing to wrap it. The list is the stack.