c 語言開發一個四則運算器,C++實現四則運算器(無括號)

本文實例為大家分享了C++實現無括號的四則運算器的具體代碼,供大家參考,具體內容如下

完成度更高的帶括號版本可以看C++實現四則運算器(帶括號)

對于無括號的計算器,實現起來比較容易,下面讓我們一步步實現。

舉例

首先明確需要實現怎樣的程序,對于無括號的計算器,大概做成這樣就可以了:

52+34*3-4/2=

分析

對于例子中的表達式,由于乘除運算的優先級高于加減運算,我們不能直接從左到右進行。但四則運算的規則是從左到右,先乘除后加減,對于優先級相同的運算符還是可以從左到右運算的。

? 因此我們可以每讀到一個運算符時,檢查前一個運算符的優先級,如果前一個運算符的優先級與當前運算符相等或更高,那么我們便可以完成前一個運算符的計算;反之,則不進行運算。這樣一來就需要將之前的運算符以及運算符左右的數保存起來,由于我們每次都是取前一個運算符,符合后進先出的條件,故可以選擇棧來存儲數據和符號。最好將數據和符號分開存儲,這里為了簡便(整數棧即可存儲數字也可存儲字符),只實現整數的四則運算,若需要浮點數的運算,稍加修改即可。

首先,實現一個棧的類,或者直接使用STL

//Stack.h

#ifndef STACK_H

#define STACK_H

#include

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)

{

*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()

{//棧擴容

std::cout << "正在擴容中..." << 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.cpp

#include"stack.h"

#include

using namespace std;

bool is_digit(char i)

{//是數字

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=='=')

return true;

else return false;

}

bool get_priority(char pre,char cur)

{//獲取兩個符號間的優先級,pre為靠前的字符,cur為靠后的字符

if ((pre == '+' || pre == '-') && (cur == '*' || 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+5*4-345+36/6*4+145*4*5-52=

*/

int main()

{

stack_int s;

stack_int num_stack;//數據棧

stack_int ope_stack;//符號棧

char current_char;

current_char = getchar();

bool overflag = false;

while (overflag!=true)

{//未遇到=號時不斷進行四則運算

if (is_digit(current_char))

{//遇到數字符號則將完整的數解析出來并保存于棧中

int num = 0;

num = current_char - '0';//符號轉數字

current_char = getchar();//獲取下一個字符

while (is_digit(current_char))

{

num = num * 10+(current_char-'0');

current_char = getchar();

}

num_stack.push(num);

//cout <

}

if (current_char == ' ')

{//空格則繼續

current_char = getchar();

continue;

}

if (is_operator(current_char))

{//遇到運算符則將運算符保存于運算符棧中

int ope = '?';

//如果當前符號棧非空,則不斷根據優先級決定是否進行一次運算

while((!ope_stack.isEmpty())&&(get_priority((char)ope_stack.gettop(),current_char)))

{//如果前一個運算符優先級更高

ope_stack.pop(ope);

//cout << "找到了前一個運算符為: " << (char)ope << endl;

int lnum, rnum;

//符號棧非空時,數據棧應該至少有兩個數,否則出錯

if (num_stack.isEmpty())

{

cout << "數據棧缺失兩個元素,解析失敗!" << endl;

overflag = true;

break;

}

num_stack.pop(rnum);

if (num_stack.isEmpty())

{

cout << "數據棧缺失一個元素,解析失敗!" << endl;

overflag = true;

break;

}

num_stack.pop(lnum);

lnum = do_operation(lnum, (char)ope, rnum);//進行運算

num_stack.push(lnum);

}

if (current_char == '=')

{//如果解析到=號了,解析完成

overflag = true;

break;

}

ope_stack.push(current_char);

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";

return 0;

}

這里需要注意一些問題,首先,由于整數可能是多位數,因此在遇到一個數字符號時,我們可以通過循環將后面幾位全部找出,并將符號轉化為真正的數值。

第二個問題就是有時候會出現表達式解析到等號了,卻有很多數沒進行運算,解決這個問題的方法就是在

if (is_operator(current_char))

中使用while循環,并將循環條件設置為棧非空且棧頂運算符優先級高于當前讀入的運算符(前提是=的優先級小于任何運算符)

while((!ope_stack.isEmpty())&&(get_priority((char)ope_stack.gettop(),current_char)))

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/541689.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/541689.shtml
英文地址,請注明出處:http://en.pswp.cn/news/541689.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

iOS開發之解決系統數字鍵盤無文字時delete鍵無法監聽的技巧

最近在做用戶登錄獲取驗證碼時添加圖形驗證碼功能&#xff0c;就是只有正確輸入圖形驗證碼才能收到后臺發送的短信驗證碼。效果如下&#xff1a; 看起來雖然是個小功能&#xff0c;但是實際操作起來&#xff0c;會發現蘋果給我們留下的坑&#xff0c;當然更多的是自己給自己挖的…

c ++查找字符串_C ++結構| 查找輸出程序| 套裝1

c 查找字符串Program 1: 程序1&#xff1a; #include <iostream>#include <math.h>using namespace std;struct st {int A NULL;int B abs(EOF EOF);} S;int main(){cout << S.A << " " << S.B;return 0;}Output: 輸出&#xff1a…

二級c語言加油,二級C語言 備考指南及常見問題(2013版)

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓3、關于上機操作部分的復習最好買一本上機題庫方面的教材&#xff0c;或打印、閱讀南開百題之類的電子文檔。配合上機模擬軟件(無紙化考試軟件)&#xff0c;上機練習是必須的。上機軟件一般有100套題多一點&#xff0c;每套有程序填…

開放定址散列表

再散列之后散列函數要重新計算。 // kaifangliaobiao.cpp : 定義控制臺應用程序的入口點。 //使用平方探測解決沖突問題時&#xff0c;散列表至少空一半時&#xff0c;總能插入一個新的元素#include "stdafx.h" #include<iostream> using namespace std;#ifnde…

合并兩個鏈表數據結構c語言,合并兩個鏈表.

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓#include #define N1 10#define N2 10struct list{int date ;struct list *next;};main(){struct list *p1,*p2,*p3,*p4,*head,*head1,*head2,*p;int n0;head1head2NULL;p1p2(struct list *)malloc(sizeof(struct list));p1->da…

c ++查找字符串_C ++結構| 查找輸出程序| 套裝2

c 查找字符串Program 1: 程序1&#xff1a; #include <iostream>using namespace std;int main(){typedef struct{int A;char* STR;} S;S ob { 10, "india" };S* ptr;ptr &ob;cout << ptr->A << " " << ptr->STR[2];…

連接fiddler后手機無法顯示無網絡

升級了fiddler到4.6版本&#xff0c;手機設置代理后提示無網絡&#xff0c;試試以下解決方法&#xff1a; 1.fiddler升級后對應的.net framework也要升級&#xff0c;安裝最新的.net framework 4.6&#xff0c;升級安裝后&#xff0c;可以正確抓包啦 2.如果上述方法無效&#x…

android 人臉解鎖 鎖屏動畫,人臉保護鎖(人臉識別鎖屏)

這是一款十分炫酷的鎖屏工具&#xff0c;還記得電影中的特工所用的人臉識別鎖嗎&#xff1f;這款應用也能讓你過過癮&#xff01;人臉識別鎖屏安卓版是一款用人臉做密碼來打開手機屏保鎖的一個APP。不僅可以作屏保鎖&#xff0c;也可以單獨保護某些重要程序不被偷窺,例如查看短…

dbms_排名前50位的DBMS面試問答

dbms1) What are the drawbacks of the file system which is overcome on the database management system? 1)在數據庫管理系統上克服的文件系統有哪些缺點&#xff1f; Ans: Data redundancy & isolation, difficulty in accessing data, data isolation, and integri…

linux時間

CST代表中國標準時間rtc實時時鐘linux主要有兩種時間硬件時鐘 clock系統時鐘 date修改時間 date 03300924必須是兩位或者 date -s 2017:03:30將系統時間同步到硬件時間 hwclock -w將硬件時間同步到系統時間 hwclock -s轉載于:https://blog.51cto.com/12372297/1911608

查找Python中給定字符串的所有排列

Python itertools Module Python itertools模塊 "itertools" are an inbuilt module in Python which is a collection of tools for handling iterators. It is the most useful module of Python. Here, a string is provided by the user and we have to print a…

android 圖片疊加xml,Android實現圖片疊加效果的兩種方法

本文實例講述了Android實現圖片疊加效果的兩種方法。&#xff0c;具體如下&#xff1a;效果圖&#xff1a;第一種&#xff1a;第二種&#xff1a;第一種是通過canvas畫出來的效果:public void first(View v) {// 防止出現Immutable bitmap passed to Canvas constructor錯誤Bit…

Win10系列:VC++ 定時器

計時器機制俗稱"心跳"&#xff0c;表示以特定的頻率持續觸發特定事件和執行特定程序的機制。在開發Windows應用商店應用的過程中&#xff0c;可以使用定義在Windows::UI::Xaml命名空間中的DispatcherTimer類來創建計時器。DispatcherTimer類包含了如下的成員&#xf…

dbms系統 rdbms_DBMS與傳統文件系統之間的區別

dbms系統 rdbmsIntroduction 介紹 DBMS and Traditional file system have some advantages, disadvantages, applications, functions, features, components and uses. So, in this article, we will discuss these differences, advantages, disadvantages and many other …

android 百度地圖api密鑰,Android百度地圖開發獲取秘鑰之SHA1

最近在做一個關于百度地圖的開發。不過在正式開發之前還必須要在百度地圖API官網里先申請秘鑰&#xff0c;而在申請秘鑰的過程中&#xff0c;就需要獲取一個所謂的SHA1值。如上所示&#xff0c;但是由于不是正式開發&#xff0c;所以以上的發布版和開發版的SHA1可以先填寫相同。…

單位矩陣的逆| 使用Python的線性代數

Prerequisites: 先決條件&#xff1a; Defining a Matrix 定義矩陣 Identity Matrix 身份矩陣 There are matrices whose inverse is the same as the matrices and one of those matrices is the identity matrix. 有些矩陣的逆與矩陣相同&#xff0c;并且這些矩陣之一是單位…

華為榮耀七能升級鴻蒙系統嗎,華為鴻蒙系統來了,你知道哪些華為手機榮耀手機可以升級嗎?...

從鴻蒙系統第一次開始登場&#xff0c;到現在慢慢有許多鴻蒙系統設備出現&#xff0c;手機市場的格局似乎又要升級變化了。科技樹兒了解到&#xff0c;在某數碼博主經過和相關人員的溝通核實之后&#xff0c;目前暫定的是搭載華為麒麟710芯片以上的機型&#xff0c;無論華為或榮…

day5-shutil模塊

一、簡述 我們在日常處理文件時&#xff0c;經常用到os模塊&#xff0c;但是有的時候你會發現&#xff0c;像拷貝、刪除、打包、壓縮等文件操作&#xff0c;在os模塊中沒有對應的函數去操作&#xff0c;下面我們就來講講高級的 文件、文件夾、壓縮包 處理模塊&#xff1a;shuti…

matlab中now函數_now()方法以及JavaScript中的示例

matlab中now函數JavaScript now()方法 (JavaScript now() method) now() method is a Date class method, it is used to current time in milliseconds, it returns the total number of milliseconds since 01st January 1970, 00:00:00 UTC. now()方法是Date類的一種方法&am…

android 集成x5內核時 本地沒有,騰訊瀏覽服務-接入文檔

三、SDK集成步驟1. 第一步下載 SDK jar 包放到工程的libs目錄下&#xff0c;將源碼和XML里的系統包和類替換為SDK里的包和類&#xff0c;具體對應如下&#xff1a;系統內核SDK內核android.webkit.ConsoleMessagecom.tencent.smtt.export.external.interfaces.ConsoleMessageand…