Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import std.stdio;
- import std.process;
- import std.container;
- import std.typecons;
- import std.conv;
- import std.array;
- import std.string;
- alias double function(double, double) OpFn;
- alias Tuple!(uint, OpFn) Binder;
- double Calculate(string Expression, in Binder[immutable char] Operators) {
- alias Tuple!(double, char) Pair;
- Pair[] stack;
- stack.assumeSafeAppend();
- double Result = 0, newNum;
- char oldOperator = '\0', newOperator;
- while (true) {
- try {
- newNum = parse!double(Expression);
- } catch (ConvException e) {
- if (Expression.front == '(') {
- stack ~= Pair(Result, -oldOperator);
- oldOperator = '\0';
- Expression = Expression[1 .. Expression.length];
- continue;
- } else {
- throw new Exception("Invaild charactor");
- }
- }
- NEXT:
- if (Expression.empty)
- break;
- newOperator = parse!char(Expression);
- if (!(newOperator in Operators)) {
- if (newOperator == ')') {
- Result = Operators[oldOperator][1](Result, newNum);
- while (true) {
- if (stack.empty)
- throw new Exception("Unexpected ')'");
- if (stack.back[1] > 0) {
- Result = Operators[stack.back[1]][1](stack.back[0], Result);
- stack.popBack();
- } else {
- oldOperator = -stack.back[1];
- newNum = Result;
- Result = stack.back[0];
- stack.popBack();
- goto NEXT;
- }
- }
- Expression = Expression[1 .. Expression.length];
- } else {
- throw new Exception("Invaild operator");
- }
- }
- if (Operators[newOperator][0] > Operators[oldOperator][0]) {
- stack ~= tuple(Result, oldOperator);
- Result = newNum;
- } else {
- Result = Operators[oldOperator][1](Result, newNum);
- if (Operators[newOperator][0] < Operators[oldOperator][0]) {
- while (!stack.empty && stack.back[1] > 0 &&
- Operators[newOperator][0] < Operators[stack.back[1]][0]) {
- Result = Operators[stack.back[1]][1](stack.back[0], Result);
- stack.popBack();
- }
- }
- }
- oldOperator = newOperator;
- }
- Result = Operators[oldOperator][1](Result, newNum);
- while (!stack.empty) {
- if (stack.back[1] <= 0)
- throw new Exception("No matching ')'");
- Result = Operators[stack.back[1]][1](stack.back[0], Result);
- stack.popBack();
- }
- return Result;
- }
- void main(string[] argv) {
- Binder[immutable char] Operators;
- Operators['+'] = Binder(1u, (double x, double y) => x + y);
- Operators['-'] = Binder(1u, (double x, double y) => x - y);
- Operators['*'] = Binder(2u, (double x, double y) => x * y);
- Operators['/'] = Binder(2u, (double x, double y) => x / y);
- Operators['\0'] = Binder(uint.max, (double x, double y) => y);
- string s = stdin.readln().chomp;
- try {
- stdout.writeln(Calculate(s, Operators));
- } catch (Exception e) {
- stderr.writeln(e.msg);
- }
- system("PAUSE");
- }
Advertisement
Add Comment
Please, Sign In to add comment