思路:輸入一個字符串,首先找到等號將其分爲左右兩部分,左部分爲變量,右部分爲運算式,分別處理。
對於左邊部分,直接記錄下來變量名最後輸出即可。
右邊部分,是一個算術表達式。首先將其由中綴表達式變爲後綴表達式,然後對後綴表達式求值即可。在求值過程中會有一些變量,我們利用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;
}