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

C++實(shí)現(xiàn)四則運(yùn)算器(帶括號(hào))

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

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

基本分析可以看另一篇文章:C++實(shí)現(xiàn)四則運(yùn)算器(無(wú)括號(hào))

棧的實(shí)現(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則棧已空無(wú)法出棧
 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)
{//是運(yùn)算符
 if (i == '+' || i == '-' || i == '*' || i == '/' || i == '(' || i == ')'||i=='=')
 return true;
 else return false;
}
bool get_priority(char pre,char cur)
{//獲取兩個(gè)符號(hào)間的優(yōu)先級(jí),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)=
先乘除,后加減,有括號(hào)先算括號(hào)內(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;//符號(hào)棧
 char current_char;
 current_char = getchar();
 bool overflag = false;//結(jié)束標(biāo)志
 bool errorflag = false;//出錯(cuò)標(biāo)志
 while (overflag != true)
 {//未遇到=號(hào)時(shí)不斷進(jìn)行四則運(yùn)算
 if (is_digit(current_char))
 {//遇到數(shù)字符號(hào)則將完整的數(shù)解析出來(lái)并保存于棧中
 int num = 0;
 num = current_char - '0';//符號(hào)轉(zhuǎn)數(shù)字
 current_char = getchar();//獲取下一個(gè)字符
 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))
 {//遇到運(yùn)算符則將運(yùn)算符保存于運(yùn)算符棧中
 int ope = '?';
 //如果當(dāng)前符號(hào)棧非空,則不斷根據(jù)優(yōu)先級(jí)決定是否進(jìn)行一次運(yùn)算
 while ((!ope_stack.isEmpty()) && (get_priority((char)ope_stack.gettop(), current_char)))
 {//如果前一個(gè)運(yùn)算符優(yōu)先級(jí)更高
 ope_stack.pop(ope);
 //cout << "找到了前一個(gè)運(yùn)算符為: " << (char)ope << endl;
 int lnum, rnum;
 //符號(hào)棧非空時(shí),數(shù)據(jù)棧應(yīng)該至少有兩個(gè)數(shù),否則出錯(cuò)
 if (num_stack.isEmpty())
 {
  cout << "error: 數(shù)據(jù)棧缺失兩個(gè)元素,解析失?。? << endl;
  errorflag = true;
  overflag = true;
  break;
 }
 num_stack.pop(rnum);
 if (num_stack.isEmpty())
 {
  cout << "error: 數(shù)據(jù)棧缺失一個(gè)元素,解析失??!" << endl;
  errorflag = true;
  overflag = true;
  break;
 }
 num_stack.pop(lnum);
 lnum = do_operation(lnum, (char)ope, rnum);//進(jìn)行運(yùn)算
 num_stack.push(lnum);
 }
 if (current_char == '=')
 {//如果解析到=號(hào)了,解析完成
 if (!ope_stack.isEmpty())
 {
  errorflag = true;
  cout << "error: 缺失)" << endl;
 }
 overflag = true;
 break;
 }
 ope_stack.push(current_char);
 if (current_char == ')')
 {//右括號(hào)則出棧兩次,將右括號(hào)和匹配的左括號(hào)出棧
 ope_stack.pop(ope);
 if (ope_stack.isEmpty())
 {
  cout << "error: 沒(méi)有與)相匹配的(" << 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ù)四則運(yùn)算器|" << endl;
 cout << " --------------" << endl;
 cout << "功能介紹:進(jìn)行整數(shù)表達(dá)式的四則運(yùn)算" << endl;
 cout << "可以使用的運(yùn)算符:+ - * /" << endl;
 cout << "使用方式:輸入以=結(jié)尾的算數(shù)運(yùn)算表達(dá)式,回車后即可得到運(yùn)算結(jié)果" << endl;
 cout << endl;
 //2432+5423-534*42=
 while (true)
 {
 cout << "____________________" << endl;
 cout << "--------------------" << endl;
 cout << "> ";
 do_arithmetic();
 }
 return 0;
}

程序大部分與不帶括號(hào)版本很相似,主要更改了兩個(gè)方面:

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

2.對(duì)于右括號(hào),令右括號(hào)左邊的運(yùn)算符(除左括號(hào)外)優(yōu)先級(jí)均高于右括號(hào),并且當(dāng)右括號(hào)左邊的符號(hào)為左括號(hào)時(shí),兩個(gè)括號(hào)相抵消,左括號(hào)退棧。

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

    C++類與對(duì)象深入之運(yùn)算符重載與const及初始化列表詳解

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

    C語(yǔ)言實(shí)現(xiàn)反彈球游戲

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

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

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

    淺談C++模板元編程

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

最新評(píng)論