您的位置:首页 > 其它

【表达式运算】hdu hdoj 3000 A Simple Language

2010-04-20 00:15 302 查看
好久没有做表达式运算的题目了,,重新看了好久。。。。

这题和一般的表达式运算有些不同,要处理等号这种运算。。



其实等号运算的优先级可以看成是除(外最低的。。。

具体的运算符优先级可以去查看c++之类的书籍,参考一下就ok了。。



另外变量值的储存可以用map来实现。。。



代码注释十分详细,大家看吧。。。



#pragma warning( disable : 4786 )
#include <iostream>
#include <string>
#include <map>
using namespace std;

#define STRLEN 1000
//获取优先级
int GetPriority(char oper)
{
	switch (oper)
	{
	case '(':
		return 0;
		break;
	case '=':
		return 1;
		break;
	case '+':
		return 2;
		break;
	case '-':
		return 2;
		break;
	case '*':
		return 3;
		break;
	case '/':
		return 3;
		break;
	}
}
//判断是否应该计算
bool IsCalc(char inStack, char outStack)
{
	return GetPriority(inStack)>=GetPriority(outStack);
}
//分词标志
bool IsSplit(char c)
{
	if (c == '+' || 
		c == '-' ||
		c == '*' ||
		c == '/' ||
		c == '(' ||
		c == ')' ||
		c == '=')
		return true;
	else
		return false;
}

//true is oper, false is num
bool GetNext(char STR[], int &s, char ans[])
{
	int i = s, j = 0;
	int len = strlen(STR);
	bool flag = false;
	for (; i<len; i++)
	{
		if (IsSplit(STR[i]))
		{
			if (j == 0)
			{
				ans[j++] = STR[i++];
				flag = true;
			}
			break;
		} else {
			ans[j++] = STR[i];
		}
	}
	ans[j] = 0x00;
	s = i;
	return flag;
}

//判断是否是数字
bool IsNum(char s[])
{
	if (s[0] >= '0' && s[0] <= '9' || s[0] == '-')
		return true;
	else
		return false;
}

int Calc(int a, int b, char oper)
{
	switch(oper)
	{
	case '+':
		return a+b;
		break;
	case '-':
		return a-b;
		break;
	case '*':
		return a*b;
		break;
	case '/':
		return a/b;
		break;
	}
}

void GetTrueStr(char str[])
{
	int len = strlen(str);
	int i;
	for (i = len-1; i>=0; i--)
		if (str[i] == ';')
			str[i] = 0x00;
		else
			break;
}

int main()
{
	char STR[STRLEN];
	char OperStack[STRLEN];
	char NumStack[STRLEN][100];
	char ans[STRLEN];
	char PutToNumStack[STRLEN];
	int OperTop, NumTop, StrPos;
	//从符号栈中取出的元素
	char cTopOper;
	//从数字栈中取出的元素。
	char a[STRLEN], b[STRLEN];
	//计算用到的,c为结果
	int NumA, NumB, NumC;
	//int NumC to string sNumC
	char sNumC[STRLEN];
	//MAP
	map<string, int> t_map;
	int len;
	bool isFuShu;
	while (cin.getline(&STR[1], STRLEN))
	{
		//memset
		memset(OperStack, 0, sizeof(OperStack));
		memset(NumStack, 0, sizeof(NumStack));
		memset(ans, 0, sizeof(ans));
		isFuShu = false;
		//前加(
		STR[0] = '(';
		//去多余的;
		GetTrueStr(STR);
		len = strlen(STR);
		//最后加)
		STR[len++] = ')';
		STR[len] = 0x00;
		//将原来的20+20的表达式串构造成(20+20)这种形式
		
		StrPos = OperTop = NumTop = 0;
		while (StrPos < len)
		{
			//如果是操作符
			if (GetNext(STR, StrPos, ans))
			{
				//如果此数为负数,也就是(-100)这样的形式
				if (ans[0] == '-' && STR[StrPos-1] == '(')
				{
					isFuShu = true;
					continue;
				}
				//如果为(则入栈
				if (ans[0] == '(')
				{
					OperStack[OperTop++] = ans[0];
				}
				//如果为右括号,则计算到左括号为止
				else if (ans[0] == ')')
				{
					//取栈顶符号
					while ((cTopOper = OperStack[--OperTop]) != '(')
					{
						//如果符号为等号,则进行赋值操作
						if (cTopOper == '=')
						{
							strcpy(b, NumStack[--NumTop]);
							strcpy(a, NumStack[--NumTop]);
							if (IsNum(b))
								NumB = atoi(b);
							else
								NumB = t_map[b];
							t_map[a] = NumB;
							//结果压回栈
							strcpy(NumStack[NumTop++], b);
						} else {
							strcpy(b, NumStack[--NumTop]);
							strcpy(a, NumStack[--NumTop]);
							//判断是否数字,如果不是数字就从map中取值
							if (IsNum(b))
								NumB = atoi(b);
							else
								NumB = t_map[b];
							if (IsNum(a))
								NumA = atoi(a);
							else
								NumA = t_map[a];
							//进行运算
							NumC = Calc(NumA, NumB, cTopOper);
							sprintf(sNumC, "%d", NumC);
							//结果压回栈
							strcpy(NumStack[NumTop++], sNumC);
						}
					}
				//如果是=号,则入栈
				} else if (ans[0] == '=')
				{
					OperStack[OperTop++] = ans[0];
				//如果是其他符号,则进行优先级判断
				} else {
					//如果栈顶符号优先级大于等于外面的,那么进行计算
					while (IsCalc(OperStack[OperTop-1], ans[0]))
					{
						strcpy(b, NumStack[--NumTop]);
						strcpy(a, NumStack[--NumTop]);
						//判断是否数字,如果不是数字就从map中取值
						if (IsNum(b))
							NumB = atoi(b);
						else
							NumB = t_map[b];
						if (IsNum(a))
							NumA = atoi(a);
						else
							NumA = t_map[a];
						//取出符号栈第一个符号
						cTopOper = OperStack[--OperTop];
						//进行运算
						NumC = Calc(NumA, NumB, cTopOper);
						sprintf(sNumC, "%d", NumC);
						//结果压回栈
						strcpy(NumStack[NumTop++], sNumC);
					}
					//如果外面的符号优先级大于栈顶的,则压入栈
					if (IsCalc(OperStack[OperTop-1], ans[0]) == false)
						OperStack[OperTop++] = ans[0];
				}
			} else {
			//如果不是,则把操作数入栈,这里要处理负数
				if (isFuShu)
				{
					PutToNumStack[0] = '-';
					strcpy(&PutToNumStack[1], ans);
				} else {
					strcpy(PutToNumStack, ans);
				}
				strcpy(NumStack[NumTop++], PutToNumStack);
			}
			isFuShu = false;
		}
		strcpy(a, NumStack[--NumTop]);
		if (IsNum(a))
			NumA = atoi(a);
		else
			NumA = t_map[a];
		printf("%d/n", NumA);
	}
	return 0;
}






===========hdoj 3000 A Simple Language===========

A Simple Language
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 152    Accepted Submission(s): 24

Problem Description
Professor X teaches the C Programming language in college, but he finds it's too hard for his students and only a few students can pass the exam. So, he decide to invent a new language to reduce the burden on students. 

This new language only support four data type, but the syntax is an strict subset of C. It only support assignment operation, brackets operation , addition , subtration, multiplication and division between variables and numbers. The priority of operations is the same as C. 

In order to void the problem of forgetting the eliminator ";", this new language allow to omit it. 

The variable naming rules is the same as C. 

Comments is not allowed in this language. 

Now Prof.X need to impelment this language, and the variable part is done by himself. Now Prof.X need you, a execllent ACM coder's help: Given a section of this language's code, please calculate it's return value. 
 

Input
The input contains many lines, each line is a section of codes written in the language described above, you can assume that all variables have been declared as int and have been set to 0 initially. 
 

Output
To each line of input, output an integer indicate the return value of the input line. the semicolon will only appear in the end of line, you can assume that every literal, variable's value and the intermediate results of calculation would never bigger than a short integer. 

Notice: the result may affect by assignment operation, if you don't know the exact return value of some statements such as a=3, you can try run codes such as ' printf("%d",a=3); ' in C, and check the result. 
 

Sample Input
a=3
a+b
a=a*(b+2)+c;
a+b
a/4
_hello=2*a;
 

Sample Output
3
3
6
6
1
12
 

Source
2009 Multi-University Training Contest 11 - Host by HRBEU 
 

Recommend
gaojie
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: