簡單實現計算器(資料結構)
阿新 • • 發佈:2018-11-19
文章轉載自:https://blog.csdn.net/gebushuaidanhenhuai/article/details/62932960
要想實現計算器,我們可以首先把中綴表示式轉化為字尾表示式,再計算中綴表示式的值。
具體的理論分析請檢視:http://blog.csdn.net/gebushuaidanhenhuai/article/details/62948774
#include<iostream>
#include<stack>
#include<cstring>
using namespace std;
// 首先把中綴表示式轉化為字尾表示式
//定義優先順序
int Priority(char ch)
{
int i = 0;
switch (ch)
{
case'(':
{
i = 1;
break;
}
case'+':
{
i = 2;
break;
}
case'-':
{
i = 2;
break;
}
case'*':
{
i = 3 ;
break;
}
case'/':
{
i = 3;
break;
}
case')':
{
i = 4;
break;
}
default:
{
i = -1;
break;
}
}
return i;
}
//將中綴表示式變為字尾表示式
// 藉助一個棧S 用來存放操作符
//一個數組用來存放字尾表示式
void Tonibolan(char* ch, char* arr)
{
stack <char> s; // 藉助一個棧S 用來存放操作符
int i = 0;
while (*ch != '\0')
{
if (*ch >='0'&&*ch<='9')
{
arr[i++] = *ch;
}
else if (*ch=='(') // 左括號直接入棧
{
s.push(*ch);
}
else if (*ch == ')') // 右括號從操作符棧彈出操作符,直到彈出‘)';
{
while (s.top() != '(')
{
arr[i++] = s.top();// 把操作符彈出到存有後綴表示式的數組裡
s.pop();
}
if (s.top() == '(')
{
s.pop(); //字尾表示式沒有'(' , ')'
}
}
// 存有操作符的棧為空或者 取出來的操作符的優先順序 大於 棧頂操作符的優先順序 直接入棧
else if (s.empty() || Priority(*ch) > Priority(s.top()))
{
s.push(*ch);
}
// 取出來的操作符A 優先順序小於等於操作符棧 棧頂的優先順序。
//把棧頂的操作符Pop出棧,放到字尾表示式的數組裡,直到A的優先順序大於棧頂 操作符的優先順序 ,A入操作符棧
else
{
while (Priority(*ch) <= Priority(s.top()))
{
arr[i++] = s.top();
s.pop();
if (s.empty())
{
break;
}
}
s.push(*ch);
}
++ch;
}
while (!s.empty())
{
arr[i++] = s.top();
s.pop();
}
}
//計算字尾表示式
//遍歷儲存字尾表示式的列表,將元素依次進棧,當遇到操作符時,
//連續出棧兩個元素,進行運算,再將結果進棧,最後棧內留下的元素就是計算結果
int Calcval(char* ret)
{
stack<char> st;
//遍歷字尾表示式
while (*ret != '\0')
{
if (*ret >= '0'&&*ret <='9') //若果是數字直接入棧
{
st.push(*ret);
}
else
{
//遇到操作符,連續出棧兩個元素,進行運算,在將結果入棧
switch (*ret)
{
case'+':
{
char a = st.top();
st.pop();
char b = st.top();
st.pop();
st.push(((a - '0') + (b - '0')) + '0');
break;
}
case'-':
{
char a = st.top();
st.pop();
char b = st.top();
st.pop();
st.push(((b - '0') - (a - '0')) + '0');
break;
}
case'*':
{
char a = st.top();
st.pop();
char b = st.top();
st.pop();
st.push(((b - '0') * (a - '0')) + '0');
break;
}
case'/':
{
char a = st.top();
st.pop();
char b = st.top();
st.pop();
if (a != '0')
{
st.push(((b - '0') / (a - '0')) + '0');
}
else
{
cout << "除數不能為0!" << endl;
}
break;
}
default:
{
break;
}
}
}
++ret;
}
return st.top() - '0'; //棧裡面的資料就是最後的結果
}
void Test()
{
char ret[100] = { 0 };
char arr[100] = { 0 };
cout << "請輸入要計算的表示式:" << endl;
cin.get(arr, 100);
Tonibolan(arr, ret);
int len = strlen(ret);
int i = 0;
cout << "算式的逆波蘭表示式為:" << endl;
while (len--)
{
cout << ret[i++]<<" ";
}
cout << "\n算式的計算結果為:" << endl;
cout << Calcval(ret) << endl;
}
int main()
{
Test();
return 0;
}