目錄
- 前言
- 1. 題目
- 1.1 題目描述
- 1.2 題目決議
- 2. 思路分析
- 3. 代碼實作
- 3.1 頭檔案
- 3.2 stack.cpp檔案
- 3.3 test.cpp檔案
- 4. 思考
前言
hello,大家好,博主確實是一個懶人,題海求知這個專欄,一晃鴿了近兩個月了,本人十分羞愧,博主是一個行動力不怎么強的人,怎么才能自律一點啊?歡迎大家給出建議,閑言少敘,讓我們來看看今天博主要分享的這道題目,
1. 題目
1.1 題目描述
輸入包含+、-、*、/、圓括號和正整陣列成的中綴算術運算式,以@作為運算式結束符,計算該運算式的運算結果,
1.2 題目決議
運算子位于兩個運算元中間的運算式稱為中綴運算式,在運算程序中,要考慮括號的作用,也要考慮運算子的先后次序和優先級,因此在求值時不能簡單的從左向右計算,必須先算運算子級別搞的,同一級別才能從左往右,這稱為算符優先級法,
算符間的優先級關系表如下:

2. 思路分析
當我們看到這個題目的時候,我們就要想,既然要實作算符優先級,我們就要先找到優先級最高的呀,那優先級較低的是不是要先存盤起來呢?而先存盤進去的優先級最低,最后運算,也就是要最后取出,于是,我們順著這個思路就可以想到,堆疊是最好的實作方式,如果有小伙伴對堆疊不是很了解,可以參考博主以前的文章堆疊:在尾巴上搞事情,
那么這道題的具體實作思路如下:


我們以一個運算式為例子來分析一下這個程序:

3. 代碼實作
3.1 頭檔案
#ifndef STACK_H
#define STACK_H
#include<iostream>
using namespace std;
template <class T, int MaxSize>
class Stack
{
T data[MaxSize];
int top;
public:
Stack();
void PushStack(T x);
T PopStack();
T TopStack();
};
#endif
3.2 stack.cpp檔案
#define CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
#include<iostream>
using namespace std;
template<class T,int MaxSize>
Stack<T, MaxSize>::Stack()
{
top = -1;
}
template<class T, int MaxSize>
void Stack<T, MaxSize>::PushStack(T x)
{
if (top == MaxSize - 1)
{
cerr << "上溢" << endl;
exit(-1);
}
else
{
top++;
data[top] = x;
}
}
template<class T, int MaxSize>
T Stack<T, MaxSize>::PopStack()
{
if (top == - 1)
{
cerr << "下溢" << endl;
exit(-1);
}
else
{
T x=data[top];
top--;
return x;
}
}
template<class T, int MaxSize>
T Stack<T, MaxSize>::TopStack()
{
if (top == MaxSize - 1)
{
cerr << "上溢" << endl;
exit(-1);
}
else
{
return data[top];
}
}
3.3 test.cpp檔案
#include"Stack.cpp"
#include<iostream>
using namespace std;
char Precede(char c1,char c2)
{
if (c1 == '+')
{
if (c2 == '+'||c2=='-'||c2==')'||c2=='@')
return '>';
if (c2 == '*' || c2 == '/' || c2 == '(')
return '<';
}
if (c1 == '-')
{
if (c2 == '+' || c2 == '-' || c2 == ')' || c2 == '@')
return '>';
if (c2 == '*' || c2 == '/' || c2 == '(')
return '<';
}
if (c1 == '*')
{
if (c2 == '+' || c2 == '-' || c2 == '*' || c2 == '/' || c2 == ')' || c2 == '@')
return '>';
if (c2 == '(')
return '<';
}
if (c1 == '/')
{
if (c2 == '+' || c2 == '-' || c2 == '*' || c2 == '/' || c2 == ')' || c2 == '@')
return '>';
if (c2 == '(')
return '<';
}
if (c1 == '(')
{
if (c2 == '+' || c2 == '-' || c2 == '*' || c2 == '/' || c2 == '(')
return '<';
if (c2 == ')')
return '=';
}
if (c1 == ')')
{
if (c2 == '+' || c2 == '-' || c2 == '*' || c2 == '/' || c2 == ')'||c2=='@')
return '>';
}
if (c1 == '@')
{
if (c2 == '+' || c2 == '-' || c2 == '*' || c2 == '/' || c2 == '(')
return '<';
if (c2 == '@')
return '=';
}
}
double Operate(double o1,char o2,double o3)
{
if (o2 == '+')
return o1 + o3;
if (o2 == '-')
return o1 - o3;
if (o2 == '*')
return o1*o3;
if (o2 == '/')
return o1 / o3;
}
int main()
{
cout << "請輸入運算式以@結尾\n";
char ch = getchar();
char preop;
double a;
double b;
Stack<char, 20>StackOPTR;
Stack<double, 20>StackOPND;
StackOPTR.PushStack('@');
while (ch != '@' || StackOPTR.TopStack() != '@')
{
if (ch >= '0'&&ch <= '9')
{
StackOPND.PushStack(ch - '0');
ch = getchar();
}
else
{
preop = StackOPTR.TopStack();
switch (Precede(preop, ch))
{
case '<':
StackOPTR.PushStack(ch);
ch = getchar();
break;
case '=':
StackOPTR.PopStack();
ch = getchar();
break;
case '>':
b=StackOPND.PopStack();
a = StackOPND.PopStack();
preop = StackOPTR.PopStack();
StackOPND.PushStack(Operate(a,preop,b));
break;
}
}
}
cout << StackOPND.TopStack() << endl;
}
4. 思考
這個程式雖然可以實作算符優先級求值,但每一個運算元只能是小于10的整數,應用范圍比較小,如果要改進這個情況,將小數和兩位數以上的數引入,則需要在放資料進堆疊時,將相鄰的字符組成一個數字存盤,博主正在嘗試完善,歡迎大家期待后續更為完美的版本,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/356149.html
標籤:其他
