实验报告
实验五:实现用波兰表达式(先序)和逆波兰表达式(后序)求算术表达式的值
要求:仅用一个栈实现(并且用原生单链表实现)
测试用例:4+2*3-10/5
交作业时间:5月14日
思路
两个步骤:
- 将给定的表达式转换为波兰表达式/逆波兰表达式
- 对转换后的式子进行计算
学习遍历二叉树,利用前序/中序/后序表达式的时候,经常有一个问题就是:
- 给出中缀表达式,【写出&&编程出】后序(逆波兰)表达式
上面的是课堂上在纸上的书写,那么如何将其用编程语言实现呢?思路应该是这样的:
- 遍历表达式:对遍历的元素进行判断
- 是运算符?操作数?还是括号呢?对其相应的判断
- 操作数
- 运算符:+-*/
- 括号
- 个位数/双位数……的字符处理
- 给出中缀表达式,【写出&&编程出】前序(波兰)表达式
如果写出了逆波兰表达式,转换为波兰表达式只需要将(
变为)
,同时遍历从后往前遍历即可
最后的结果逆置
- 最后的计算,波兰和逆波兰不能写成一个函数,因为减数和被减数,除数和被除数的缘故
实验代码
#include<bits/stdc++.h>
using namespace std;
/**
- 波兰表达式/逆波兰表达式求解运算表达式
- /
/**
- 单链表的存储结构
- /
typedef struct LNode {
string data; //数据域
struct LNode *next; //指针域
}Lnode, *LinkList; //LinkList为指向结构体LNode的指针类型
/* 初始化链表 */
void InitList(LinkList &L) {
L = new LNode;
L->next = NULL;
}
/* 打印 */
void TraverseList(LinkList & L){
LNode *p = new LNode;
p = L->next;
// cout << "此中缀表达式链表打印的结果为:";
while (p != NULL)
{
cout << p->data;
p = p->next;
}
cout << "\n";
}
/* 逆置 */
void ReverseList(LinkList &L) {
LNode *p = L->next;
L->next = NULL;
while(p)
{
LNode *q = p->next;
p->next = L->next;
L->next = p;
p = q;
}
}
/**
- 初始化用户输入的链表
- /
void Center(LinkList &L,string s) {
InitList(L);
LinkList p = L;
string temp = "";
for (int i = 0; i < s.length();i++){ // 处理双位数字情况
if (isdigit(s[i])) {
// 该字符为数字
temp = temp + s[i];
if (!isdigit(s[i+1])) {
// 下一个不是数字,而是字符,将temp后插
LinkList node = new LNode;
node->data = temp;
node->next = NULL;
p->next = node;
p = node;
// 将temp重置
temp = "";
continue;
}
continue;
}
// 后插到L尾巴上
LinkList node = new LNode;
node->data = s[i];
node->next = NULL;
p->next = node;
p = node;
}
}
/**
将表达式转换为波兰表达式/逆波兰表达式
第二个参数对逆波兰而言是左括号,第三个参数对逆波兰而言是右括号
对波兰而言反过来
/
void Transition(LinkList &L, string l, string r){
// 定义一个栈用来处理
stack<string> stack;
LinkList p = L->next;
LinkList result = new LNode;
InitList(result);
LinkList result_a = result;
while(p != NULL) {
if (p->data == l) {
stack.push(p->data);
} else if(p->data == r) {
while(stack.top() != l){
LinkList temp = new LNode;
temp->data = stack.top();
temp->next = NULL;
result_a->next = temp;
result_a = temp;
stack.pop();
}
if (stack.top() == l){
stack.pop();
}
} else if(p->data == "+" || p->data == "-") {
if (stack.size() != 0) {
if (stack.top() == "*" || stack.top() == "/"){
for (int i = 0; i < stack.size();i++) {
if (stack.top() == l) {
break;
}
LinkList temp = new LNode;
temp->data = stack.top();
temp->next = NULL;
result_a->next = temp;
result_a = temp;
stack.pop();
}
}
}
stack.push(p->data);
} else if(p->data == "*" || p->data == "/") {
stack.push(p->data);
} else {
LinkList temp = new LNode;
temp->data = p->data;
temp->next = NULL;
result_a->next = temp;
result_a = temp;
}
p = p->next;
}
// TraverseList(result);
for (int i = 0; i < stack.size();i++) {
LinkList temp = new LNode;
temp->data = stack.top();
temp->next = NULL;
result_a->next = temp;
result_a = temp;
stack.pop();
}
// 上一个操作总是不能清空栈的最后一个元素
LinkList temp = new LNode;
temp->data = stack.top();
temp->next = NULL;
result_a->next = temp;
result_a = temp;
stack.pop();
L = result;
}
/**
- 计算
- /
void EvaulTree(LinkList &L) {
// 定义一个栈用来处理
stack<string> stack;
LinkList p = L->next;
while(p != NULL) {
if (p->data == "+"){
int x = stoi(stack.top());
stack.pop();
int y = stoi(stack.top());
stack.pop();
stack.push(to_string(y + x));
} else if(p->data == "-") {
int x = stoi(stack.top());
stack.pop();
int y = stoi(stack.top());
stack.pop();
stack.push(to_string(y - x));
} else if(p->data == "*") {
int x = stoi(stack.top());
stack.pop();
int y = stoi(stack.top());
stack.pop();
stack.push(to_string(y * x));
} else if(p->data == "/") {
int x = stoi(stack.top());
stack.pop();
int y = stoi(stack.top());
stack.pop();
stack.push(to_string(y / x));
} else {
stack.push(p->data);
}
p = p->next;
}
while (!stack.empty()){
cout << stoi(stack.top());
stack.pop();
}
}
void EvaulTree_polish(LinkList &L) {
// 定义一个栈用来处理
stack<string> stack;
LinkList p = L->next;
while(p != NULL) {
if (p->data == "+"){
int x = stoi(stack.top());
stack.pop();
int y = stoi(stack.top());
stack.pop();
stack.push(to_string(x + y));
} else if(p->data == "-") {
int x = stoi(stack.top());
stack.pop();
int y = stoi(stack.top());
stack.pop();
stack.push(to_string(x - y));
} else if(p->data == "*") {
int x = stoi(stack.top());
stack.pop();
int y = stoi(stack.top());
stack.pop();
stack.push(to_string(x * y));
} else if(p->data == "/") {
int x = stoi(stack.top());
stack.pop();
int y = stoi(stack.top());
stack.pop();
stack.push(to_string(x / y));
} else {
stack.push(p->data);
}
p = p->next;
}
while (!stack.empty()){
cout << stoi(stack.top());
stack.pop();
}
}
int main () {
cout << "————————————"<<"\n";
string s;
cout << "请输入运算表达式:"<<"\n";
cin >> s;
LinkList test_reversepolish = new LNode;
InitList(test_reversepolish);
LinkList test_polish = new LNode;
InitList(test_polish);
Center(test_reversepolish, s);
Center(test_polish, s);
cout << "------------------------------------"<<"\n";
// 波兰表达式
ReverseList(test_polish);
Transition(test_polish, ")", "(");
cout << "波兰表达式为:";
ReverseList(test_polish);
TraverseList(test_polish);
cout << "波兰表达式计算结果为:";
ReverseList(test_polish);
EvaulTree_polish(test_polish);
cout << "\n"<<"------------------------------------"<<"\n";
// 逆波兰表达式
Transition(test_reversepolish, "(", ")");
cout << "逆波兰表达式为:";
TraverseList(test_reversepolish);
cout << "逆波兰表达式计算结果为:";
EvaulTree(test_reversepolish);
cout << "\n"<<"------------------------------------"<<"\n";
}
评论区