kiddy

arithmetic expression validation

leave a comment »

Write code to do arithmetic expression validation:
digits: 0..9
operators: +, -, (, )

E.g.:
1+2-3 valid
1+(2-(3+4)) valid
-2 not valid

enum NTYPE{
		num = 0, oper = 1, left = 2, right = 3, invalid = 4
	};
	
struct Node{
	NTYPE type;
	int number;
	char oper;
	Node(NTYPE t, char c, int n): type(t){
		if(t == NTYPE::num){
			number = n;
		}else{
			oper = c;
		}
	}
};

NTYPE getType(char c){
	if(c >= '0' && c <= '9')	return NTYPE::num;
	if(c == '+' || c == '-')	return NTYPE::oper;
	if(c == '(')	return NTYPE::left;
	if(c == ')')	return NTYPE::right;
	return NTYPE::invalid;
}


void pushNum(stack<Node*> &ss, int cur_val){
	bool flagAdd = false;
	if(ss.size() >= 2){
		Node *top1 = ss.top(); ss.pop();
		Node *top2 = ss.top(); ss.pop();
		if(top1->type == NTYPE::oper && top2->type == NTYPE::num){
			cur_val =(top1->oper == '+' ? top2->number+cur_val:top2->number-cur_val);
			delete top1, top2;
			pushNum(ss,cur_val);
			flagAdd = true;
		}else{
			ss.push(top2);
			ss.push(top1);
		}		
	}
	if(!flagAdd)	ss.push(new Node(NTYPE::num, '0', cur_val));
	
}

bool pushRight(stack<Node*> &ss){
	if(ss.size() < 2) return false;
	bool flagRet = true;
	Node *top1 = ss.top(); ss.pop();
	Node *top2 = ss.top(); ss.pop();
	if(top1->type != NTYPE::num || top2->type != NTYPE::left)	{
		flagRet = false;
	}else{
		pushNum(ss,top1->number);
	}
	delete top1, top2;
	return flagRet;
}
			
			
bool valid(string s){
	int size = s.size();
	if(size == 0)	return true;
	stack<Node*> ss;
	for(int i = 0; i < size; i++){
		char cur = s[i];
		NTYPE cur_type = getType(cur);
		if(cur_type == NTYPE::invalid)	return false;
		if(cur_type == NTYPE::num){
			int cur_val = cur-'0';
			pushNum(ss, cur_val);
		}else if(cur_type == NTYPE::right){
			if(!pushRight(ss)) return false;
		}else if(cur_type == NTYPE::left){
			ss.push(new Node(NTYPE::left, '0', 0));
		}else if(cur_type == NTYPE::oper){
			ss.push(new Node(NTYPE::oper, cur, 0));
		}		
	}
	if(ss.size()!= 1 || ss.top()->type != NTYPE::num)	return false;
	cout<<"result is:"<<ss.top()->number<<endl;
	return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
	//string input= "1+(((2+3)-4)+(4+5))";
	string input= "-2";
	bool flag = valid(input);
	cout<<flag<<endl;

	return 0;
}

Written by linzhongzl

November 11, 2013 at 9:08 pm

Posted in Others

Leave a comment