欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實現(xiàn)四則運算器(帶括號)

 更新時間:2020年11月25日 14:21:57   作者:shadowgully  
這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)四則運算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了C++實現(xiàn)四則運算器的具體代碼,供大家參考,具體內(nèi)容如下

基本分析可以看另一篇文章:C++實現(xiàn)四則運算器(無括號)

棧的實現(xiàn)

//stack.h
#ifndef STACK_H
#define STACK_H
#include<iostream>
class stack_int
{
private:
 int* bottom;   //棧底
 int* top;    //棧頂
 unsigned int capacity;//棧容量
 unsigned int size; //棧大小
public:
 stack_int() :bottom(new int[11]), top(bottom), capacity(10), size(0) {};
 stack_int(unsigned int capacity) :bottom(new int[capacity+1]),top(bottom), capacity(capacity),size(0){};
 int operator[](unsigned int i) const
 {
 return *(bottom + i);
 }
 bool isEmpty()const { return bottom == top; }
 bool isFull()const { return size == capacity-1; }
 unsigned int getsize()const { return size; }
 unsigned int getcapacity()const { return capacity; }
 int gettop()const
 {
 if (!isEmpty())
 return *(top - 1);
 else
 return -1;
 }
 void settop(int i)
 {
 if (!isEmpty())
 {
 *(top - 1) = i;
 }
 }
 void push(int i)
 {
 if ((top - bottom)<capacity)
 {
 *top = i;
 top++;
 size++;
 }
 else
 {
 std::cout << "stack full!" << std::endl;
 stack_expansion();
 push(i);
 }
 }
 int pop(int &val)
 {//返回值為1則棧未空,返回值為0則棧已空無法出棧
 if (top > bottom)
 {
 top--;
 size--;
 val = *top;
 return 1;
 }
 else
 {
 std::cout << "stack empty!" << std::endl;
 return NULL;
 }
 }
private:
 void stack_expansion()
 {//棧擴(kuò)容
 std::cout << "正在擴(kuò)容中..." << std::endl;
 int newcapacity = 2 * capacity + 1;
 int* newbottom = new int[newcapacity + 1];
 int* newtop = newbottom;
 for (int i = 0; i < size; ++i)
 {
 *newtop = *bottom;
 newtop++;
 bottom++;
 }
 bottom = newbottom;
 top = newtop;
 capacity = newcapacity;
 }
};

#endif

主程序

//Main.c
#include"stack.h"
#include<iostream>
using namespace std;
bool is_digit(char i)
{//是數(shù)字
 if (i == '1' || i == '2' || i == '3' || i == '4' || i == '5' || i == '6' || i == '7' || i == '8' || i == '9' || i == '0')
 return true;
 else return false;
}
bool is_operator(char i)
{//是運算符
 if (i == '+' || i == '-' || i == '*' || i == '/' || i == '(' || i == ')'||i=='=')
 return true;
 else return false;
}
bool get_priority(char pre,char cur)
{//獲取兩個符號間的優(yōu)先級,pre為靠前的字符,cur為靠后的字符
 if ((pre == '+' || pre == '-') && (cur == '*' || cur == '/'))
 return false;
 else if (pre == '(' || cur == '(')
 return false;
 else
 return true;
}
int do_operation(int lnum, char ope, int rnum)
{
 if (ope == '+')
 return lnum + rnum;
 if (ope == '-')
 return lnum - rnum;
 if (ope == '*')
 return lnum * rnum;
 if (ope == '/')
 return lnum / rnum;
}
/*
1+2*3=
1*(2+1*(3+5)+4*3)=
先乘除,后加減,有括號先算括號內(nèi)的
1+5*4-345+36/6*4+145*4*5-52=
*/

void do_arithmetic()
{
 stack_int s;
 stack_int num_stack;//數(shù)據(jù)棧
 stack_int ope_stack;//符號棧
 char current_char;
 current_char = getchar();
 bool overflag = false;//結(jié)束標(biāo)志
 bool errorflag = false;//出錯標(biāo)志
 while (overflag != true)
 {//未遇到=號時不斷進(jìn)行四則運算
 if (is_digit(current_char))
 {//遇到數(shù)字符號則將完整的數(shù)解析出來并保存于棧中
 int num = 0;
 num = current_char - '0';//符號轉(zhuǎn)數(shù)字
 current_char = getchar();//獲取下一個字符
 while (is_digit(current_char))
 {
 num = num * 10 + (current_char - '0');
 current_char = getchar();
 }
 num_stack.push(num);
 //cout <<"the number is " <<num << endl;
 }
 if (current_char == ' '||current_char=='\n')
 {//空格或換行則繼續(xù)
 current_char = getchar();
 continue;
 }
 if (is_operator(current_char))
 {//遇到運算符則將運算符保存于運算符棧中
 int ope = '?';
 //如果當(dāng)前符號棧非空,則不斷根據(jù)優(yōu)先級決定是否進(jìn)行一次運算
 while ((!ope_stack.isEmpty()) && (get_priority((char)ope_stack.gettop(), current_char)))
 {//如果前一個運算符優(yōu)先級更高
 ope_stack.pop(ope);
 //cout << "找到了前一個運算符為: " << (char)ope << endl;
 int lnum, rnum;
 //符號棧非空時,數(shù)據(jù)棧應(yīng)該至少有兩個數(shù),否則出錯
 if (num_stack.isEmpty())
 {
  cout << "error: 數(shù)據(jù)棧缺失兩個元素,解析失??!" << endl;
  errorflag = true;
  overflag = true;
  break;
 }
 num_stack.pop(rnum);
 if (num_stack.isEmpty())
 {
  cout << "error: 數(shù)據(jù)棧缺失一個元素,解析失?。? << endl;
  errorflag = true;
  overflag = true;
  break;
 }
 num_stack.pop(lnum);
 lnum = do_operation(lnum, (char)ope, rnum);//進(jìn)行運算
 num_stack.push(lnum);
 }
 if (current_char == '=')
 {//如果解析到=號了,解析完成
 if (!ope_stack.isEmpty())
 {
  errorflag = true;
  cout << "error: 缺失)" << endl;
 }
 overflag = true;
 break;
 }
 ope_stack.push(current_char);
 if (current_char == ')')
 {//右括號則出棧兩次,將右括號和匹配的左括號出棧
 ope_stack.pop(ope);
 if (ope_stack.isEmpty())
 {
  cout << "error: 沒有與)相匹配的(" << endl;
  errorflag = true;
  overflag = true;
  break;
 }
 ope_stack.pop(ope);
 }
 current_char = getchar();
 }
 }
 //for (int i = 0; i < num_stack.getsize(); ++i)
 // cout << num_stack[i] << "\t";
 //cout << endl;
 //for (int i = 0; i < ope_stack.getsize(); ++i)
 // cout << (char)ope_stack[i] << "\t";
 if (!errorflag)
 cout << num_stack.gettop() << endl;
}

int main()
{
 cout << " ______________" << endl;
 cout << "|整數(shù)四則運算器|" << endl;
 cout << " --------------" << endl;
 cout << "功能介紹:進(jìn)行整數(shù)表達(dá)式的四則運算" << endl;
 cout << "可以使用的運算符:+ - * /" << endl;
 cout << "使用方式:輸入以=結(jié)尾的算數(shù)運算表達(dá)式,回車后即可得到運算結(jié)果" << endl;
 cout << endl;
 //2432+5423-534*42=
 while (true)
 {
 cout << "____________________" << endl;
 cout << "--------------------" << endl;
 cout << "> ";
 do_arithmetic();
 }
 return 0;
}

程序大部分與不帶括號版本很相似,主要更改了兩個方面:

1.對于左括號,令左括號左邊運算符優(yōu)先級低于左括號,右邊運算符優(yōu)先級高于左括號(即,只要含有左括號的比較結(jié)果均為無法進(jìn)行運算,函數(shù)get_priority返回值永遠(yuǎn)為false)。

2.對于右括號,令右括號左邊的運算符(除左括號外)優(yōu)先級均高于右括號,并且當(dāng)右括號左邊的符號為左括號時,兩個括號相抵消,左括號退棧。

遇到右括號時,兩括號內(nèi)的+ - * /運算全部可以進(jìn)行,直到符號棧棧頂為左括號。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 如何利用OpenGL畫坐標(biāo)軸指示圖

    如何利用OpenGL畫坐標(biāo)軸指示圖

    C++用opengl繪制出的二維坐標(biāo),簡單明了,很容易理解,下面這篇文章主要給大家介紹了關(guān)于如何利用OpenGL畫坐標(biāo)軸指示圖的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • C++AVL樹4種旋轉(zhuǎn)詳講(左單旋、右單旋、左右雙旋、右左雙旋)

    C++AVL樹4種旋轉(zhuǎn)詳講(左單旋、右單旋、左右雙旋、右左雙旋)

    AVL樹即平衡二叉搜索樹,平衡因子bf=右子樹的高度-左子樹的高度,bf為0,-1,1時,此樹即平衡,下面這篇文章主要給大家介紹了關(guān)于C++AVL樹4種旋轉(zhuǎn)(左單旋、右單旋、左右雙旋、右左雙旋)的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • C語言版飛機(jī)大戰(zhàn)游戲

    C語言版飛機(jī)大戰(zhàn)游戲

    這篇文章主要為大家詳細(xì)介紹了C語言版飛機(jī)大戰(zhàn)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • C語言匯編分析傳遞結(jié)構(gòu)體指針比傳遞結(jié)構(gòu)體變量高效的深層原因

    C語言匯編分析傳遞結(jié)構(gòu)體指針比傳遞結(jié)構(gòu)體變量高效的深層原因

    本文章使用的工具是vs2010,本篇文章主要講解結(jié)構(gòu)體指針作為參數(shù)傳遞與結(jié)構(gòu)體變量作為參數(shù)傳遞的對比,不談值傳遞與址傳遞的概念
    2022-10-10
  • C語言菜鳥基礎(chǔ)教程之常量和變量

    C語言菜鳥基礎(chǔ)教程之常量和變量

    在C語言中,常量和變量都是可以用來存儲和表示數(shù)據(jù)的,常量值在程序執(zhí)行的過程中是不可變的,而變量是可變的
    2017-10-10
  • C語言深入探究程序的編譯之預(yù)處理

    C語言深入探究程序的編譯之預(yù)處理

    在C語言的程序中包括各種以符號#開頭的編譯指令,這些指令稱為預(yù)處理命令。預(yù)處理命令屬于C語言編譯器,而不是C語言的組成部分,通過預(yù)處理命令可擴(kuò)展C語言程序設(shè)計的環(huán)境
    2022-05-05
  • C++類與對象深入之運算符重載與const及初始化列表詳解

    C++類與對象深入之運算符重載與const及初始化列表詳解

    運算符是程序中最最常見的操作,例如對于內(nèi)置類型的賦值我們直接使用=賦值即可,因為這些編譯器已經(jīng)幫我們做好了,但是對象的賦值呢?能直接賦值嗎
    2022-06-06
  • C語言實現(xiàn)反彈球游戲

    C語言實現(xiàn)反彈球游戲

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)反彈球游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 一篇文章詳細(xì)解釋C++的友元(friend)

    一篇文章詳細(xì)解釋C++的友元(friend)

    這篇文章主要為大家詳細(xì)介紹了C++的友元(friend),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 淺談C++模板元編程

    淺談C++模板元編程

    本篇文章主要介紹了淺談C++模板元編程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12

最新評論