Пример #1
0
 void pop() {
     if(left.empty()) {
         while(!right.empty()) {
             left.push(right.top());
             right.pop();
         }
     }
     left.pop();
 }
Пример #2
0
 int top() {
     if(left.empty()) {
         while(!right.empty()) {
             left.push(right.top());
             right.pop();
         }
     }
     return left.top();
 }
Пример #3
0
double Utils::evaluate(QString exp)
{
	auto priority = [](QChar o){
		switch (o.unicode())
		{
		case '(':
			return 1;
		case '+':
		case '-':
			return 2;
		case '*':
		case '/':
			return 3;
		case '+' + 128:
		case '-' + 128:
			return 4;
		case ':':
		case ':' + 128:
			return 5;
		default:
			return 0;
		}
	};
	exp.remove(' ');
	QString pst;
	SStack<QChar> opt;
	int i = 0;
	opt.push('#');
	while (i < exp.length()){
		if (exp[i].isDigit() || exp[i] == '.'){
			pst.append(exp[i]);
		}
		else{
			auto tra = [&](){
				pst.append(' ');
				while (priority(exp[i]) <= priority(opt.top())){
					pst.append(opt.pop());
				}
				opt.push(exp[i]);
			};
			int colon = 0;
			switch (exp[i].unicode()){
			case '(':
				opt.push(exp[i]);
				break;
			case ')':
				while (opt.top() != '('){
					pst.append(opt.pop());
				}
				opt.pop();
				break;
			case '+':
			case '-':
			{
				if ((i == 0 || (!exp[i - 1].isDigit() && exp[i - 1] != ')')) && (i + 1) < exp.length() && (exp[i + 1].isDigit() || exp[i + 1] == '(')){
					exp[i].unicode() += 128;
				}
				tra();
				break;
			}
			case ':':
				switch (colon++){
				case 2:
					exp[i].unicode() += 128;
				case 1:
				case 0:
					break;
				default:
					throw std::runtime_error("colon overflow");
				}
				tra();
				break;
			case '*':
			case '/':
				tra();
				break;
			default:
				throw std::runtime_error("token unrecognized");
			}
		}
		++i;
	}
	while (!opt.isEmpty()){
		pst.append(opt.pop());
	}
	SStack<double> num;
	i = 0;
	while (pst[i] != '#'){
		if (pst[i].isDigit() || pst[i] == '.'){
			double n = 0;
			while (pst[i].isDigit()){
				n = n * 10 + pst[i++].toLatin1() - '0';
			}
			if (pst[i] == '.'){
				++i;
				double d = 1;
				while (pst[i].isDigit()){
					n += (d /= 10)*(pst[i++].toLatin1() - '0');
				}
			}
			num.push(n);
		}
		else{
			switch (pst[i].unicode()){
			case '+' + 128:
				num.push(+num.pop());
				break;
			case '-' + 128:
				num.push(-num.pop());
				break;
			case '+':
			{
				double r = num.pop(), l = num.pop();
				num.push(l + r);
				break;
			}
			case '-':
			{
				double r = num.pop(), l = num.pop();
				num.push(l - r);
				break;
			}
			case '*':
			{
				double r = num.pop(), l = num.pop();
				num.push(l*r);
				break;
			}
			case '/':
			{
				double r = num.pop(), l = num.pop();
				num.push(l / r);
				break;
			}
			case ':':
			{
				double r = num.pop(), l = num.pop();
				num.push(l * 60 + r);
				break;
			}
			case ':' + 128:
			{
				double r = num.pop(), l = num.pop();
				num.push(l * 24 + r);
				break;
			}
			}
			i++;
		}
	}
	return num.top();
}