資料結構__不含括號的加減乘除法混合運算
阿新 • • 發佈:2018-11-07
這個程式我一共寫了5個檔案,4個是標頭檔案,最後1個則是main函式的cpp檔案。
第一個檔名為head.h
用於包含一些基本的標頭檔案,如下所示:
#pragma once
#include<iostream>
#include<stdlib.h>
#include<string>
using namespace std;
第二個檔名為stack.h
用於定義基本的棧和相應的棧操作,如下所示:
#pragma once #include"head.h" struct node { double data; node *next; public: node(); }; node::node() {} class stack { private: node* top; public: stack() { top = NULL; } ~stack(); void push(double e); double pop(); double getTop(); bool isEmpty() { if (top == NULL) return true; else return false; } }; double stack::getTop() { if (top != NULL) return top->data; } stack::~stack() { node* p; while (top) { p = top->next; delete top; top = p; } } void stack::push(double e) { node* p = new node; if (!p) { cout << "記憶體分配失敗" << endl; return; } p->data = e; p->next = top; top = p; } double stack::pop() { if (top == NULL) { cout << "溢位" << endl; } double temp = top->data; node* p = top; top = top->next; delete p; return temp; }
第三個檔名是queue.h
用於定義基本的佇列和相關的操作,如下:
#pragma once #include"head.h" struct Node { double data; Node *next; }; class sqqueue { private: Node *front; Node *rear; public: sqqueue(); ~sqqueue(); void enqueue(double e); double dequeue(); bool isEmpty(); double getFront(); }; double sqqueue::getFront() { return front->next->data; } sqqueue::sqqueue() { front = new Node; front->next = NULL; rear = front; } sqqueue::~sqqueue() { Node *p=NULL; while (front != NULL) { p = front; front = front->next; delete p; } } void sqqueue::enqueue(double e) { Node *s = new Node; s->data = e; s->next = rear->next; rear->next = s; rear = s; if (front->next == NULL) front->next = s; } double sqqueue::dequeue() { double e; Node *p = NULL; if (rear == front) { cout << "下溢" << endl; } p = front->next; e = p->data; front->next = p->next; if (p->next == NULL) rear = front; delete p; return e; } bool sqqueue::isEmpty() { if (rear == front) return true; else return false; }
第四個檔名是change.h
裡面有兩個函式,第一個名為change的函式作用是“逆波蘭”,第二個Cal函式則是計算字尾表示式並輸出最後的計算結果,如下:
#pragma once #include"queue.h" #include"stack.h" sqqueue output; stack s; stack a; void change(string str) { double num; double temp; for (int i = 0; i < str.length();) { if (str[i] >= '0'&&str[i] <= '9') { temp = str[i++] - '0'; while (i < str.length() && str[i] >= '0'&&str[i] <= '9') { temp = temp * 10 + (str[i] - '0'); i++; } output.enqueue(temp); } else { if (((str[i] == '+' || str[i] == '-')&&(s.getTop() == -3|| s.getTop() == -4))|| ((str[i] == '+' || str[i] == '-') && (s.getTop() == -1 || s.getTop() == -2))|| ((str[i] == '*' || str[i] == '/') && (s.getTop() == -3 || s.getTop() == -4))) { while (!s.isEmpty()) { output.enqueue(s.pop()); } } switch (str[i]) { case '+':s.push(-1); break; case '-':s.push(-2); break; case '*':s.push(-3); break; case '/':s.push(-4); break; default:break; } i++; } } while (!s.isEmpty()) { output.enqueue(s.pop()); } } void Cal() { double temp; double r, l; while (!output.isEmpty()) { if (output.getFront() >= 0) { a.push(output.dequeue()); } else { double x = output.dequeue(); if (x == -1) { r = a.pop(); l = a.pop(); temp = l + r; a.push(temp); } else if (x == -2) { r = a.pop(); l = a.pop(); temp = l - r; a.push(temp); } else if (x == -3) { r = a.pop(); l = a.pop(); temp = l * r; a.push(temp); } else if (x == -4) { r = a.pop(); l = a.pop(); temp = l / r; a.push(temp); } } } cout << a.pop() << endl; }
最後一個cpp檔案是用來寫main函式的,很簡潔,沒啥好說的。檔名就叫main.cpp:
#include"change.h"
int main(void)
{
string str;
cin >> str;
change(str);
Cal();
system("pause");
return 0;
}
個人以為,主要是第四個叫change的檔案需要注意,尤其是逆波蘭的步驟。。。。一不小心寫錯一點點就會有記憶體訪問錯誤,原因是退棧出棧入隊出隊的操作容易不小心寫混,導致讀取資料的data指標指向NULL。主要是找BUG會找很久很久。
下面展示幾個測試資料: