1. 程式人生 > >資料結構之棧與佇列數學表示式的求值

資料結構之棧與佇列數學表示式的求值

數學表示式的計算

#pragma once
#include <stack>
#include <deque>
using namespace std;


typedef struct {
	double opnd;  //運算元
	char optr;       //運算子
}Item;

const int COUNTS =6 ;             //“+-*/()”一共六個運算子,照抄書上的優先順序表格(沒有用到'#')
const char PRECEDE[COUNTS][COUNTS] = {
	{ '>', '>' ,'<' ,'<' ,'<','>'},
	{ '>','>','<','<','<' ,'>',},
	{ '>','>','>', '>', '<', '>' },
	{ '>','>','>','>', '<','>'},
	{ '<', '<', '<', '<', '<', '='},
	{ '>', '>', '>', '>', '!', '>'},
};

double Value(double a, char optr, double b);       
char Precede(char optr1, char optr2);
double EvaluateExpression(stack<Item> & stackExpression, deque<Item> dequeExpression, const char * ptrExpression);

實現介面
#include <regex>
#include <string>
#include <stack>
#include <deque>
#include"regular expression.h"
using namespace std;
 
double EvaluateExpression(stack<Item> & stackExpression, deque<Item> dequeExpression, const char * ptrExpression)
{
	int nLength;          //表示式長度
	double opnd1, opnd2;    //兩個double型別的數
	Item item;                      //Item型別物件
	const char * ptrAnalyze;
	string strToptr;
	regex rx("\\d+\\.?\\d*");                //正則表示式
	cmatch mr;                              //match_result<const char*>物件

	nLength = strlen(ptrExpression);

	for (ptrAnalyze = ptrExpression; ptrAnalyze < ptrExpression + nLength; )    
	{
		if (strchr("+-*/()", *ptrAnalyze) == nullptr)       //不是運算
		{                                                                          
			regex_search(ptrAnalyze, mr, rx);                     //使用正則表示式找出第一個數字
			ptrAnalyze += mr.length();                               //ptrAnalyze越過這個數字
			strToptr = mr.str();
			dequeExpression.push_back({ atof(strToptr.c_str()),'\0' });//atof()將字串轉化為浮點數,將數字放入佇列最後
		}
		else                //是運算子
		{
			if (stackExpression.empty())     //棧為空,直接把運算子放入棧
			{
				stackExpression.push({ 0.0,*ptrAnalyze });
				ptrAnalyze++;     //越過這個運算子
			}
			else
			{
				item = stackExpression.top();           //提取棧頂的運算子
				switch (Precede(item.optr, *ptrAnalyze))    //和棧頂運算子比較優先順序
				{
				case '<':
					stackExpression.push({ 0.0,*ptrAnalyze });        //優先順序小就入棧
					ptrAnalyze++;                 //越過這個運算子
					break;
				case '=':
					stackExpression.pop(); //相等就使棧頂元素退棧( 其實就是當 '(' 和 ')' 相遇的時候,將一對括號都拋棄)
					ptrAnalyze++;
					break;
				case '>':
					item = stackExpression.top();         //優先順序比棧頂的運算子高,就使棧頂運算子退棧並放入佇列最後
					dequeExpression.push_back(item);
					stackExpression.pop();
					break;       //注意ptrAnalyze沒有自增,依然指向此運算子,直到比較結果為'<'或'='此運算子才被處理
				default:
					break;
				}
			}
		}
	}
	while (!stackExpression.empty())       //將棧中剩餘的運算子依次取出放入佇列最後
	{
		item = stackExpression.top();
		dequeExpression.push_back(item);
		stackExpression.pop();
	}

	while (!dequeExpression.empty())                //將佇列中的元素從頭部依次放入棧中
	{
		item = dequeExpression.front();
		if (item.optr)                                       //如果是運算子,判斷是幾元運算子,取棧頂元素進行計算,結果放入棧頂
		{
			opnd2 = stackExpression.top().opnd;
			stackExpression.pop();
			opnd1 = stackExpression.top().opnd;
			stackExpression.pop();
			stackExpression.push({ Value(opnd1,item.optr,opnd2),'\0' });
			dequeExpression.pop_front();
			continue;
		}
		stackExpression.push(item);         //如果不是運算子,就將運算元放入棧頂
		dequeExpression.pop_front();
	}

	return stackExpression.top().opnd;
}

char Precede(char optr1, char optr2)   //判斷運算子優先順序
{
	int i, n;

	switch (optr1)
	{
	case '+':i = 0;break;
	case '-':i = 1;break;
	case '*':i = 2;break;
	case '/':i = 3;break;
	case '(':i = 4;break;
	case ')':i = 5;break;
	default:
		break;
	}

	switch (optr2)
	{
	case '+':n = 0;break;
	case '-':n = 1;break;
	case '*':n = 2;break;
	case '/':n = 3;break;
	case '(':n = 4;break;
	case ')':n = 5;break;
	default:
		break;
	}
	return PRECEDE[i][n];     //標頭檔案二維char陣列
}

double Value(double a, char optr, double b)   //二元操作符的運算
{
	switch (optr)
	{
	case '+':return a + b;
	case '-':return a - b;
	case '*':return a*b;
	case '/':return a / b;
	default:
		return 0.0;
		break;
	}
}
#include <iostream>
#include <regex>
#include <string>
#include <stack>
#include <deque>
#include "regular expression.h"
using namespace std;


int main()
{
	string strCin;             //表示式字串
	stack<Item> stackExpression;      //一個堆
	deque<Item> dequeExpression;    //一個佇列
	const char * ptrExrpression;

	cin >> strCin;     //輸入表示式
	ptrExrpression = strCin.c_str();    //string物件返回一個const char *
	cout << EvaluateExpression(stackExpression, dequeExpression, ptrExrpression) << endl;  //呼叫EvaluateExpression 直接出結果
}
程式碼下載

相關推薦

資料結構佇列數學表示式

數學表示式的計算 #pragma once #include <stack> #include <deque> using namespace std; typedef struct { double opnd; //運算元 char o

Python資料結構: 佇列

棧(stacks) 是一種只能通過訪問其一端來實現資料儲存與檢索的線性資料結構,具有後進先出(last in first out,LIFO)的特徵 stack = [] stack.append("A") #A入棧 stack.append("B") #B入棧 st

C語言資料結構佇列的應用(2)

輸入一個表示式,表示式中包括三種括號“()”、“[]”和“{}”,判斷該表示式的括號是否匹配。 #include<stdio.h> #include<stdlib.h> #de

資料結構佇列的面試題:判斷字串是否按照出順序

可能這個題目猛一看,並不知道題目要求是什麼,讓我們做什麼。首先我們來說說這個題目大意。 給定一個字串,如:a b d e c 一個棧的入棧順序為:a b c d e 那麼出棧順序顯而易見:e d c b a 題目意思為:字串 a b d e c 是否能按

資料結構的應用---四則運算表示式(中綴表示式字尾表示式轉換)

用計算機實現帶括號的四則運算的方式。 這裡的困難在於乘除運算的優先順序高於加減運算,並且加入了括號,使得問題變得更加困難。 20世紀50年代,波蘭邏輯學家想到了一種不需要括號的字尾表達法,我們也把它稱為逆波蘭表示。 比如:9+(3-1)*3+10/2,如果

資料結構_的應用_表示式java實現

這篇文章講述的是演算法趣味分數部分的表示式求值j問題的java實現,參考的書籍為清華大學出版社出版,賈蓓等編著的《c語言趣味程式設計1000例》,如有錯誤或者不當之處,還望各位大神批評指正。 問題描述 表示式求值,給出一個表示式包括 + - * / ( )等

學習筆記資料結構佇列

共同點 棧和佇列的訪問是受限制的,即在特定時刻只有一個數據項可以被讀取或刪除 棧 特點: 後進先出 實現: 主要機制可用陣列來實現,也可以用連結串列來實現 查詢: 棧只允許訪問一個數據項:即最後插入的資料 基本操作: 出棧(Pop)、入棧(Push)

python資料結構佇列

目錄 棧與佇列的基礎知識 使用佇列實現棧 (LeetCode 225) 使用棧實現佇列 (LeetCode 232) 包含min函式的棧(LeetCode 155) 合法的出棧序列 堆的必備基礎知識 陣列中的第K大的數 (LeetCode 215) 尋找中位

資料結構筆記-佇列python實現

概述 棧與佇列是程式設計中被廣泛應用的兩種重要的資料結構,都是在特定範圍的儲存單元記憶體儲資料,這些資料都可以被重新取出使用,與線性表相比,他們的插入和刪除受到更多的約束,固又稱限定性的線性表結構。他們是最簡單的快取結構,他們只支援資料項的儲存與訪問,不支援資料項之間的任何關係。因此,這兩種

資料結構佇列 Part1:的建立相關函式

First.棧(Stack) 定義:後進先出的線性表 操作: #include<stack> 標頭檔案 stack<int> s;      建立int型別的棧s s.push(x);         &n

資料結構佇列) java實現

棧的相關定義 package StackDef; import java.util.Arrays; import java.util.EmptyStackException; /** * 通過陣列模擬棧 * @author tian * */ public cla

資料結構佇列

棧和佇列是兩種重要的線性結構。從資料結構角度來看,棧和佇列也是線性表,它們是操作受限的線性表,被稱為限定性的資料結構。 棧(Stack) 棧是限定僅在表尾進行插入或刪除操作的線性表。 表尾端被稱為棧頂(top),表頭端稱為棧底(bottom),不含元素的空表稱為空棧。

python資料結構佇列

1.功能實現 之前文章有,可以點開看看 棧 佇列 2.應用(1)括號匹配及字尾表示式 class Solution(object): def isValid(self, s): """ :type s: str :rtype

js資料結構佇列

棧是一種遵從後進先出(LIFO)原則的有序集合。新新增的或待刪除的元素都儲存在棧末尾,稱作棧頂,另一端稱作棧底。在棧裡,新元素都靠近棧頂,舊元素就接近棧底。 佇列是遵循先進先出(FIFO)原則的一組有序的項。佇列在尾部新增新元素,並從頂部移除元素。最新新增的元

C++資料結構佇列

棧和佇列也是常用的資料結構。棧“先進後出”的性質使得它有很多的應用,如果你學過組合語言,在設計程式時,中斷出現,要響應中斷,那麼程式中的重要暫存器資訊就要壓入棧中,等中斷程式執行完把斷點處的資訊出棧;

資料結構佇列的面試題(二)

一.使用兩個佇列實現(實現棧先進後出的特點)     思路:              1.建立兩個佇列的結構體,並將這倆個佇列(Queue1和Queue2)的結構體封裝到一個結構體裡。                       2.入棧:判斷哪個佇列中為空(Queue1和

資料結構佇列的c語言程式碼實現

用一個簡單的c語言例子,用程式碼實現棧與佇列的各種程式碼。 進位制轉換    十進位制N和其他d進位制數的轉換原理: N=( N div d )*d + N mod d     其中:div為整除運算,mod為求餘運算         例如:(1348)10=(25

資料結構 學習筆記(三):線性結構:堆疊,佇列表示式,多項式加法運算

前言 2.2 堆疊 2.2.1 什麼是堆疊 計算機如何進行表示式求值? 【例】算術表示式5+6/2-3*4。正確理解: 5+6/2-3*4=5+3-3*4=8-3*4=8-12=-4 由兩類物件構成的: 運算數,如2、3、4 運算子號

資料結構實驗佇列二:一般算術表示式轉換成字尾式(SDUT 2132)

題目連結 #include <bits/stdc++.h> using namespace std; typedef long long ll; int ok(char ch, char sh) { if(sh == '(')return 1; if((ch ==

【OJ.2132】資料結構實驗佇列二:一般算術表示式轉換成字尾式

                            資料結構實驗之棧與佇列二:一般算術表示式轉換成字尾式                              Time Limit: 1000 ms