1. 程式人生 > >順序棧應用2(利用順序棧將中綴式轉換成前、字尾式並求值)

順序棧應用2(利用順序棧將中綴式轉換成前、字尾式並求值)

/*
中綴轉字首參考演算法:
1)求輸入串的逆序。(中綴轉字首是從右向左訪問表示式)
2)檢查輸入的下一元素。
3)假如是運算元,把它新增到輸出串中。
4)假如是閉括號,將它壓棧。
5)假如是運算子,
i)假如棧空,此運算子入棧。
ii)假如棧頂是閉括號,此運算子入棧。
iii)假如它的優先順序高於或等於棧頂運算子,此運算子入棧。
iv)否則,棧頂運算子出棧並新增到輸出串中,重複步驟5。
6)假如是開括號,棧中運算子逐個出棧並輸出,直到遇到閉括號。閉括號出棧並丟棄。
7)假如輸入還未完畢,跳轉到步驟2。
8)假如輸入完畢,棧中剩餘的所有操作符出棧並加到輸出串中。
9)求輸出串的逆序。
*/

/*
中綴轉字尾參考演算法:
1)求輸入串的正序。(中綴轉字尾是從左向右訪問表示式)
2)檢查輸入的下一元素。
3)假如是運算元,把它新增到輸出串中。
4)假如是開括號,將它壓棧。
5)假如是運算子,
i)假如棧空,此運算子入棧。
ii)假如棧頂是開括號,此運算子入棧。
iii)假如它的優先順序高於或等於棧頂運算子,此運算子入棧。
iv)否則,棧頂運算子出棧並新增到輸出串中,重複步驟5。
6)假如是閉括號,棧中運算子逐個出棧並輸出,直到遇到開括號。開括號出棧並丟棄。
7)假如輸入還未完畢,跳轉到步驟2。
8)假如輸入完畢,棧中剩餘的所有操作符出棧並加到輸出串中。
9)求輸出串的正序。
*/

/************************
author's email:[email protected]
date:2018.1.5
利用順序棧將中綴式轉換成前、字尾式並求值
************************/
#include <iostream>
#include<string>   
using namespace std;
#define maxSize 50
//siffix字尾式  prefix字首式   infix中綴式
int priority(char op);//判斷運算子級別函式;其中* /的級別為2,+ -的級別為1;  
bool isOperatorDigit(char op);//判斷輸入串中的字元是不是操作符,如果是返回true 
int op(int a, char Op, int b);//本函式是運算函式,用來完成算式“a Op b”的運算

string infixConvertPrefix(string s);//將一箇中綴串轉換為字首串
int calculatePrefix(string s);//計算字首式的值


string infixConvertSiffix(string s);//將一箇中綴串轉換為字尾串
int calculateSiffix(string s);//字尾式計算函式
void main() {
//測試表達式為(((((4+2)/3)*5)-4)/2)*7,其字首式為* / - * / + 4 2 3 5 4 2 7 ,其後綴式為4 2 + 3 / 5 * 4 - 2 / 7 *  ,其值為21。

	string input, output;
	cout << "請輸入字首表示式(表示式中的數字只能是個位數):";
	cin >> input;
	output = infixConvertPrefix(input);
	cout << "字首串為:";
	for (int i = output.length() - 1; i >= 0; i--)//9)求輸出串的逆序。   
		cout << output[i]<<' ';
	cout << endl;
	cout << "字首式的計算結果為:";
	cout << calculatePrefix(output) << endl;


	//string input, output;
	//cout << "請輸入字首表示式(表示式中的數字只能是個位數):";
	//cin >> input;
	//output = infixConvertSiffix(input);
	//cout << "字尾串為:";
	//for (int i = 0; i <= output.length() - 1; i++)//9)求輸出串的逆序。   
	//	cout << output[i]<<' ';
	//cout << endl;
	//cout << "字尾式的計算結果為:";
	//cout << calculateSiffix(output) << endl;

	system("pause");
}
int priority(char op)//判斷運算子級別函式;其中* /的級別為2,+ -的級別為1;   
{
	int level;
	switch (op)
	{
	case'+':
	case'-':level = 1; break;
	case'*':
	case'/':level = 2; break;
	default:level = 0; break;
	}
	return level;
}
bool isOperatorDigit(char op)//判斷輸入串中的字元是不是操作符,如果是返回true   
{
	if (op == '+' || op == '-' || op == '*' || op == '/')
		return true;
	else
		return false;
}
int op(int a, char Op, int b) {//本函式是運算函式,用來完成算式“a Op b”的運算
	if (Op == '+')return a + b;
	if (Op == '-')return a - b;
	if (Op == '*')return a*b;
	if (Op == '/')
	{
		if (b == 0)//分母為0的情況
		{
			cout << "Error" << endl;
			return 0;
		}
		else
			return a / b;
	}
}
string infixConvertPrefix(string s)//將一箇中綴串轉換為字首串,   
{
	char stack[maxSize];//定義順序棧    
	int top = -1;//棧頂指標,為-1表示棧為空; 
	string output = "";//輸出串   
	for (int i = s.length() - 1; i >= 0;)//1)求輸入串的逆序。   
	{
		if (s[i] >= 48 && s[i] <= 57)
			output = output + s[i];//3)假如是運算元,把它新增到輸出串中。   
		if (s[i] == ')')//4)假如是閉括號,將它壓棧。   
		{
			top++;
			stack[top] = s[i];
		}
		while (isOperatorDigit(s[i]))//如果是運算子,執行演算法(5)對應操作;   
		{
			if (top == -1 || stack[top] == ')' || priority(s[i]) >= priority(stack[top]))
			{
				top++;
				stack[top] = s[i];
				break;
			}
			else
			{
				output = output + stack[top];
				top--;
			}
		}
		if (s[i] == '(')//6)假如是開括號,棧中運算子逐個出棧並輸出,直到遇到閉括號。閉括號出棧並丟棄。   
		{
			while (stack[top] != ')')
			{
				output = output + stack[top];
				top--;
			}
			top--;//閉括號出棧並丟棄 
		}
		i--;//7)假如輸入還未完畢,跳轉到步驟2。   
	}
	while (top != -1)//8)假如輸入完畢,棧中剩餘的所有操作符出棧並加到輸出串中。   
	{
		output = output + stack[top];
		top--;
	}
	return output;
}
int calculatePrefix(string s) {//計算字首式的值
	int i, a, b, c;//a、b為運算元,c用來儲存結果

	/*定義順序棧,注意元素必須為int型,不能死char型。雖然要求輸入的中綴表示式
	裡面的數字都是個位數,但是運算過程中可能產生多位的數字,所以要用int型*/
	int stack[maxSize];
	int top = -1;//棧頂指標,為-1表示棧為空; 

	char Op;
	for (i = 0; i <= s.length() - 1; ++i)//注意此時字首式的逆序
	{
		if (s[i] >= 48 && s[i] <= 57)//假如是運算元,把它新增到輸出串中。
			stack[++top] = s[i] - '0';//將字元型轉化為整型併入棧
		else            //如果遇到運算子,則開始運算
		{
			Op = s[i];  //取運算子
			a = stack[top--];//取第一個運算元
			b = stack[top--];//取第二個運算元
			c = op(a, Op, b);//運算
			stack[++top] = c;//運算結果入棧
		}
	}
	return stack[top];//返回最終運算結果
}

string infixConvertSiffix(string s) 
{
	char stack[maxSize];//定義順序棧    
	int top = -1;//棧頂指標,為-1表示棧為空; 
	string output = "";//輸出串   
	for (int i = 0; i <= s.length() - 1;)//1)求輸入串的正序。   
	{
		if (s[i] >= 48 && s[i] <= 57)
			output = output + s[i];//3)假如是運算元,把它新增到輸出串中。   
		if (s[i] == '(')//4)假如是開括號,將它壓棧。   
		{
			top++;
			stack[top] = s[i];
		}
		while (isOperatorDigit(s[i]))//如果是運算子,執行演算法(5)對應操作;   
		{
			if (top == -1 || stack[top] == '(' || priority(s[i]) >= priority(stack[top]))
			{
				top++;
				stack[top] = s[i];
				break;
			}
			else
			{
				output = output + stack[top];
				top--;
			}
		}
		if (s[i] == ')')//6)假如是閉括號,棧中運算子逐個出棧並輸出,直到遇到開括號。開括號出棧並丟棄。   
		{
			while (stack[top] != '(')
			{
				output = output + stack[top];
				top--;
			}
			top--;//開括號出棧並丟棄 
		}
		i++;//7)假如輸入還未完畢,跳轉到步驟2。   
	}
	while (top != -1)//8)假如輸入完畢,棧中剩餘的所有操作符出棧並加到輸出串中。   
	{
		output = output + stack[top];
		top--;
	}
	return output;
}
int calculateSiffix(string s) {//字尾式計算函式
	int i, a, b, c;//a、b為運算元,c用來儲存結果
	
	/*定義順序棧,注意元素必須為int型,不能死char型。雖然要求輸入的中綴
	表示式裡面的數字都是個位數,但是運算過程中可能產生多位的數字,所以
	要用int型*/ 
	int stack[maxSize]; 
	int top = -1;//棧頂指標,為-1表示棧為空; 

	char Op;
	for (i = 0; i <= s.length() - 1; ++i)
	{
		if (s[i] >= 48 && s[i] <= 57)//假如是運算元,把它新增到輸出串中。
			stack[++top] = s[i] - '0';//將字元型轉化為整型併入棧
		else            //如果遇到運算子,則開始運算
		{
			Op = s[i];  //取運算子

			//注意這是這裡是和計算字首式的值的區別
			b = stack[top--];//取第二個運算元
			a = stack[top--];//取第一個運算元
			c = op(a, Op, b);//運算
			stack[++top] = c;//運算結果入棧
		}
	}
	return stack[top];//返回最終運算結果
}
以上如有錯誤,請指出,大家共同學習進步

相關推薦

順序應用2利用順序中綴轉換字尾

/* 中綴轉字首參考演算法: 1)求輸入串的逆序。(中綴轉字首是從右向左訪問表示式) 2)檢查輸入的下一元素。 3)假如是運算元,把它新增到輸出串中。 4)假如是閉括號,將它壓棧。 5)假如是運算子, i)假如棧空,此運算子入棧。 ii)假如棧頂是閉括號,此運算子入棧。 i

應用2中綴表示式轉換字尾表示式-筆記

問題:如何使用棧來實現將中綴轉換為字尾表示式的演算法? 解答:在討論演算法前,首先介紹中綴、字首和字尾表示式的定義 中綴:中綴表示式由一個單一字元或運算子,連線前後兩個中綴字串共同組成。 A A+B (A+B)+(C+D) 字首:字首表示式由一個單一字元或運算子,隨後是兩個字首字串共同組成。

利用python sklearn 類別資料轉換one-hot資料

做資料預處理的時候,經常會遇到需要將類別特徵轉換成有意義的數值的情況,通過這樣使類別資料能夠用於後續的分類預測任務。目前應用得最多的就是將其轉換成one-hot編碼。以下是通過sklearn的方法很方便地實現。 首先讀取資料: housing = pd.read_csv(

利用Jackson框架json字串轉換泛型List

Jackson處理一般的JavaBean和Json之間的轉換隻要使用ObjectMapper 物件的readValue和writeValueAsString兩個方法就能實現。但是如果要轉換複雜型別Collection如 List<YourBean>,那麼就需要先

和佇列的實現利用順序

棧的實現class Stack(object): """"棧""" def __init__(self): self.__list = [] def push(self,item): """新增一個新的元素item到棧頂"""

順序應用6:有序順序表查詢利用了二分法來提高演算法效率

順序表應用6:有序順序表查詢 Time Limit: 1000 ms Memory Limit: 4096 KiB Problem Description 順序表內按照由小到大的次序存放著n個互不相同的整數,任意輸入一個整數,判斷該整數在順序表中是否存在。如果在順序

數制轉換2利用

/* 題目:數制轉換(通過棧這個資料結構來求解) 內容:輸入M進位制的數x,輸出N進位制的數。 作答者:小白楊 收穫:1、棧這種資料結構,只允許在棧頂進行出棧入棧操作。 2、先構造出棧的基本結構,然後初始化一個棧 再勾勒出入棧和出棧的函式 再輸入M進位制的數x,轉換為int型

[順序應用2:多餘元素刪除之建表演算法]

順序表應用2:多餘元素刪除之建表演算法 Time Limit: 3 ms Memory Limit: 600 KiB Submit Statistic Problem Description 一個長度不超過10000資料的順序表,可能存在著一些值相同的“多餘”資料元素(型別為整型)

順序應用5:有序順序表歸併函式的傳遞

順序表應用5:有序順序表歸併 Time Limit: 100 ms Memory Limit: 880 KiB Problem Description 已知順序表A與B是兩個有序的順序表,其中存放的資料元素皆為普通整型,將A與B表歸併為C表,要求C表包含了A、B表裡

順序應用2:多餘元素刪除之建表演算法

Problem Description 一個長度不超過10000資料的順序表,可能存在著一些值相同的“多餘”資料元素(型別為整型),編寫一個程式將“多餘”的資料元素從順序表中刪除,使該表由一個“非純表”(值相同的元素在表中可能有多個)變成一個“純表”(值相同的元素在表中只保

順序應用5:有序順序表歸併資料結構

順序表應用5:有序順序表歸併 Time Limit: 100 ms Memory Limit: 880 KiB Submit Statistic Problem Description 已知順序表A與B是兩個有序的順序表,其中存放的資料元素皆為

順序應用5:有序順序表歸併就是想用陣列,略略略

應某人建議,我決定多寫一些思路。 順序表應用5:有序順序表歸併 Time Limit: 100 ms Memory Limit: 880 KiB Submit Statistic Problem Descriptio

應用1判定括號是否匹配-筆記

問題:如何使用棧來判定括號是否匹配 解答:對於給定的表示式,可以使用棧來實現括號匹配判定演算法。這個演算法在編譯器中非常重要。解析器每次讀入一個字元,如果字元是一個開分隔符(如(、{、或 [ ),那麼將其入棧。若讀入的是一個閉分隔符(如)、}、或 ] ),那麼將棧頂的開分隔符出棧,並與閉分隔

資料結構——應用表示式C語言

char Precede(char t1, char t2)函式用於輸出t1,t2兩個運算子的優先順序(t1為先出現的運算子(已經壓入棧OPTR中),t2為後出現的運算子) char Precede(char t1, char t2){ int

---定義應用遞迴字尾表示式實現數學表示式

一、定義 棧是限定僅在表尾進行插入和刪除操作的線性表。因此,棧的表尾端稱為棧頂;表頭端稱為棧底。不含任何資料元素的棧稱為空棧。棧又稱為後進先出(Last In First Out)的線性表,簡稱LIF0結構。 理解棧的定義需要注意:首先它是一個線性表,也即棧

應用2 中綴表示式轉字尾表示式

為了簡單起見,我們只考慮簡單的加減乘除計算 一、演算法邏輯     1)從左向右掃描字尾表示式     2)初始化棧     3)遍歷表示式,直至掃描完所有字元     4)如果被掃描的字

資料結構--非遞迴遍歷二叉樹利用輔助

#include "StdAfx.h" #include <stdio.h> #include <stdlib.h> /*非遞迴方法前序遍歷二叉樹,利用輔助棧(指標陣列實現)。由於對指標不是很熟悉,程式碼較為混亂,基本上實現遍歷的功能。

C語言利用實現中綴表示式轉換字尾表示式即逆波蘭

輸入計算表示式如:(1-3)*4+10/5 輸出的逆波蘭式:1  3  -  4  * 10  5  /   + 碼程式碼時臉上洋溢著的神祕的微笑 #include <stdio.h> #include <stdlib.h> #include

數學筆記17——定積分的應用2體積

定積分 切割 物理 區域 復雜 www 最大 加速度 es2017   定積分除了計算面積外,還可以應用在計算體積上。 圓盤法   一條曲線y = f(x),如果曲線繞x軸旋轉,則曲線經過的區域將形成一個橄欖球形狀的體積,如下圖所示: 曲線繞x軸旋轉一周   現在要計算

順序應用5:有序順序表歸併(順序表做法

順序表應用5:有序順序表歸併 Time Limit: 100 ms Memory Limit: 880 KiB Submit Statistic Problem Description 已知順序表A與B是兩個有序的順序表,其中存放的資料元素皆為普通整型,將A與B表歸併為C表,要求C