思路:输入一个字符串,首先找到等号将其分为左右两部分,左部分为变量,右部分为运算式,分别处理。
对于左边部分,直接记录下来变量名最后输出即可。
右边部分,是一个算术表达式。首先将其由中缀表达式变为后缀表达式,然后对后缀表达式求值即可。在求值过程中会有一些变量,我们利用map保存变量名对应的值即可。
参考资料:解析算术表达式[1]后缀式(逆波兰式) http://blueve.me/archives/318
调度场算法(中缀变后缀) http://zh.wikipedia.org/wiki/Shunting_yard%E7%AE%97%E6%B3%95
map的有关用法
存在问题:1.不能处理浮点数
2.不能处理负数
附上源码:
#include<iostream>
#include<string>
#include<map>
#include<cstdio>
using namespace std;
bool compare(char a,char b)//比较a与b的优先级
{
int preference[100];
preference['+'] = 1;
preference['-'] = 1;
preference['*'] = 2;
preference['/'] = 2;
preference['('] = 3;
if(preference[a] > preference[b])
return true;
return false;
}
int operation(int x,int y,char z)
{
switch(z)
{
case '+':
return x+y;
case '-':
return x-y;
case '*':
return x*y;
case '/':
return x/y;
}
}
int main()
{
freopen("in.txt","r",stdin);
int i,j,k;
map <char,int>my_map;
string whole_string;
while(cin >> whole_string)
{
int split;
for(i=0;i<whole_string.size();i++)
if(whole_string[i] == '=')
{
split = i;
break;
}
//从split+1到最后都为算术表达式
int length = whole_string.size()-split-1;//length即为之后算式的长度
bool ok=true;//判断是否仅为赋值语句
for(i=2;i<=2+length-1;i++)
if(whole_string[i]<'0'||whole_string[i]>'9')
ok = false;
if(ok)//仅为赋值语句直接赋值即可
{
int tem_number = 0;
for(i=2;i<=2+length-1;i++)
tem_number = tem_number*10 + whole_string[i] - '0';
my_map[whole_string[0]] = tem_number;
}
else//将中值式变为后缀式
{
int top_output=0,top_sign=0;//两个栈顶指针(数组模拟栈)
char output[1000][1000];
char sign[1000];
char str[1000];
for(i=0;i<length;i++)
str[i] = whole_string[split+1+i];//将整个运算式复制到str中
//cout << str << endl;
for(i=0;i<length;i++)
{
if(str[i]>='0'&&str[i]<='9')//是数字压入输出栈
{
for(j=i+1;j<length;j++)
if(str[j]<'0'||str[j]>'9')
break;
for(k=0;k<j-i;k++)
output[top_output][k] = str[i+k];
output[top_output++][k] = '\0';
i = j-1;
}
else if((str[i]>='a'&&str[i]<='z')||str[i]>='A'&&str[i]<='Z')//是字母将其对应的数字压入栈
{
char tem_char[1000];
int tem_count = 0;
int tem_number = my_map[str[i]];
//cout << "tem:" << tem_number << endl;
while(tem_number)//将数字转成char存入output栈
{
tem_char[tem_count++] = tem_number%10 + '0';
tem_number/=10;
}
for(j=0;j<tem_count;j++)
{
output[top_output][j] = tem_char[tem_count-j-1];
}
output[top_output++][j] = '\0';
}
else //字符对其进行操作
{
if(top_output==0)
sign[top_sign++] = str[i];
else
{
if(str[i] == ')')//当为右括号将符号弹入输出栈直至左括号
{
while(sign[top_sign-1]!='(')
{
output[top_output][0] = sign[top_sign-1];
output[top_output++][1] = '\0';
top_sign--;
}
top_sign--;
}
else
{
if(top_sign==0)
sign[top_sign++] = str[i];
else
{
//读入符号优先级大于栈顶元素优先级将其压入符号栈
if(compare(str[i],sign[top_sign-1])||sign[top_sign-1]=='(')
sign[top_sign++] = str[i];
//若读入符号优先级小于栈顶元素则将栈顶元素弹出到输出栈并将符号压入符号栈
else
{
output[top_output][0] = sign[top_sign-1];
output[top_output++][1] = '\0';
top_sign--;
sign[top_sign++] = str[i];
}
}
}
}
}
}
while(top_sign)//符号栈不为空
{
output[top_output][0] = sign[top_sign-1];
output[top_output++][1] = '\0';
top_sign--;
}
//开始对后缀表达式求值(栈)
int top_ans=0;
int ans[1000];
for(i=0;i<top_output;i++)
{
if(output[i][0]>='0'&&output[i][0]<='9')//若为数字存入栈
{
int tem = 0;
//从0到k-1为一个数
for(k=1;;k++)
if(output[i][k]=='\0')
break;
for(j=0;j<=k-1;j++)
tem = tem*10 + output[i][j] - '0';
ans[top_ans++] = tem;
}//ans[top_ans++] = output[i]-'0';
else //若为操作符进行操作
{
ans[top_ans-2] = operation(ans[top_ans-2],ans[top_ans-1],output[i][0]);
top_ans--;
}
}
my_map[whole_string[0]] = ans[0];
//cout << ans[0] << endl;
}
cout << whole_string[0] << "=" << my_map[whole_string[0]] << endl ;
}
return 0;
}