C++代碼實現(xiàn)逆波蘭表達式
本文實例為大家分享了C++實現(xiàn)逆波蘭表達式的具體代碼,供大家參考,具體內(nèi)容如下
當我們輸入一個數(shù)學(xué)表達式,是中綴表達式,我們首先轉(zhuǎn)換為后綴表達式(逆波蘭表達式),然后再進行求值。
在《大話數(shù)據(jù)結(jié)構(gòu)》的104-100頁有詳細的介紹,下面是我理解之后的代碼實現(xiàn)。
代碼思路:
(1)首先對輸入的中綴表達式合法性進行判斷,bool isStringLegal(const char* str); 函數(shù)實現(xiàn)。
(2)然后把中綴表達式轉(zhuǎn)換為后綴表達式。
(3)根據(jù)后綴表達式求出結(jié)果,double getTheResult(vector<string> &vec);函數(shù)實現(xiàn)。
注意:表達式的運算符可以輸入 加、減、乘、除、括號,輸入的數(shù)據(jù)為整形數(shù)據(jù),計算結(jié)果為double型數(shù)據(jù)。
#include <iostream>
#include <math.h>
#include <map>
#include <vector>
#include <string.h>
#include <memory>
#include <string>
#include <stdio.h>
#include <stack>
#include <stdlib.h>
using namespace std;
#define MAX_STRING_LENGTH 100
/* 解析當前的整形數(shù)據(jù),并把整形數(shù)據(jù)轉(zhuǎn)換為string型 */
string analyData(const char* str, int &i);
/* 根據(jù)逆波蘭表達式求表達式的值 */
double getTheResult(vector<string> &vec);
/* 判斷該字符是否是 + - * / ( ) */
bool isCalChar(const char ch);
/* 判斷輸入的中綴表達式是否合法 */
bool isStringLegal(const char* str);
/* 解析當前的整形數(shù)據(jù),并把整形數(shù)據(jù)轉(zhuǎn)換為string型 */
string analyData(const char* str, int &i)
{
int temp = i++;
while(str[i] >= '0' && str[i] <= '9' && str[i] != '\0')
{
i++;
}
string s(str+temp,str+i);
return s;
}
/* 根據(jù)逆波蘭表達式求表達式的值 */
double getTheResult(vector<string> &vec)
{
vector<string>::iterator it;
stack<double> sta;
string strTemp;
double d = 0, d1 = 0, d2 = 0;
for(it = vec.begin(); it != vec.end(); it++)
{
strTemp = (*it);
if(strTemp == "+")
{
d1 = sta.top();
sta.pop();
d2 = sta.top();
sta.pop();
d = d1 + d2;
sta.push(d);
}
else if(strTemp == "-")
{
d1 = sta.top();
sta.pop();
d2 = sta.top();
sta.pop();
d = d2 - d1;
sta.push(d);
}
else if(strTemp == "*")
{
d1 = sta.top();
sta.pop();
d2 = sta.top();
sta.pop();
d = d2 * d1;
sta.push(d);
}
else if(strTemp == "/")
{
d1 = sta.top();
sta.pop();
d2 = sta.top();
sta.pop();
d = d2 / d1;
sta.push(d);
}
else
{
const char *p = strTemp.c_str();
d = atoi(p);
sta.push(d);
}
}
return sta.top();
}
/* 判斷該字符是否是 + - * / ( ) */
bool isCalChar(const char ch)
{
if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')')
{
return true;
}
return false;
}
/* 判斷輸入的中綴表達式是否合法 */
bool isStringLegal(const char* str)
{
/* 判斷是否是空串 */
if(NULL == str)
{
return false;
}
int len = strlen(str);
int i = 0;
int flag = 0;
/* 字符串的開頭和末尾是否是數(shù)字 */
if(str[0] > '9' || str[0] < '0' || str[len-1] > '9' || str[len-1] < '0')
{
return false;
}
for(i = 0; str[i] != '\0'; i++)
{
/* 是否有除了加減乘除括號之外的字符 */
if(isCalChar(str[i]) == false)
{
return false;
}
/* 判斷是否有兩個連續(xù)的符號 */
if(i < len-1 && isCalChar(str[i]) == true)
{
if(isCalChar(str[i+1]) == true)
{
return false;
}
}
/* 判斷括號是否成對 */
if(str[i] == '(')
{
flag++;
}
else if(str[i] == ')')
{
flag--;
}
/* 判斷是否出現(xiàn) )( 這樣的情況 */
if(flag < 0)
{
return false;
}
}
/* 判斷括號是否匹配 */
if(flag != 0)
{
return false;
}
return true;
}
int main(void)
{
char str[MAX_STRING_LENGTH] = {0};
int i = 0;
string data;
/* 存放運算符表達式的棧 */
stack<char> oper_char;
/* 存放后綴表達式 */
vector<string> post_str;
/* 輸入中綴的表達式 */
gets(str);
/* 判斷輸入的中綴表達式是否合法 */
if(isStringLegal(str) != true)
{
cout << "This expression is not legal." << endl;
}
else
{
/* 將中綴表達式轉(zhuǎn)換為后綴表達式 */
for(i = 0; str[i] != '\0'; i++)
{
/* 如果該字符為數(shù)字,解析該數(shù)字,并壓入棧 */
if(str[i] >= '0' && str[i] <= '9')
{
data = analyData(str,i);
post_str.push_back(data);
i--;
}
else if(str[i] == '(')
{
oper_char.push(str[i]);
}
else if(str[i] == ')')
{
char chtemp[2] = {0};
chtemp[0] = oper_char.top();
while(chtemp[0] != '(')
{
string strtemp(chtemp);
post_str.push_back(strtemp);
oper_char.pop();
chtemp[0] = oper_char.top();
}
oper_char.pop();
}
else if(str[i] == '+' || str[i] == '-')
{
char chtemp[2] = {0};
/* 全部出棧,但是碰到 '('就要停止出棧 */
while(oper_char.size() != 0)
{
chtemp[0] = oper_char.top();
if(chtemp[0] == '(')
{
break;
}
oper_char.pop();
string strtemp(chtemp);
post_str.push_back(strtemp);
}
/*將當前的表達式符號入棧*/
oper_char.push(str[i]);
}
else if(str[i] == '*' || str[i] == '/')
{
char chtemp[2] = {0};
while(oper_char.size() != 0)
{
chtemp[0] = oper_char.top();
if(chtemp[0] == '(' || chtemp[0] == '+' || chtemp[0] == '-')
{
break;
}
else
{
oper_char.pop();
string strtemp(chtemp);
post_str.push_back(strtemp);
}
}
/*將當前的表達式符號入棧*/
oper_char.push(str[i]);
}
}
/* 存放表達式的??赡苓€有數(shù)據(jù) */
while(!oper_char.empty())
{
char chtemp[2] = {0};
chtemp[0] = oper_char.top();
oper_char.pop();
string strtemp(chtemp);
post_str.push_back(strtemp);
}
/* 把逆波蘭表達式求值 */
cout << getTheResult(post_str) << endl;
}
return 0;
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于vs strcpy_s()和strcat_s()用法探究
這篇文章主要介紹了關(guān)于vs strcpy_s()strcat_s()用法,本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
關(guān)于C++中的static關(guān)鍵字的總結(jié)
C++的static有兩種用法:面向過程程序設(shè)計中的static和面向?qū)ο蟪绦蛟O(shè)計中的static。前者應(yīng)用于普通變量和函數(shù),不涉及類;后者主要說明static在類中的作用2013-09-09
C/C++ 獲取Windows系統(tǒng)的位數(shù)32位或64位的實現(xiàn)代碼
這篇文章主要介紹了C/C++ 獲取Windows系統(tǒng)的位數(shù)32位或64位的實現(xiàn)代碼的相關(guān)資料,希望通過本文能幫助到大家,讓大家實現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10

