從零實現一個簡易計算器

最近在刷算法題時,遇到了實現計算器的問題。一開始覺得很簡單,但真正動手實現時才發現其中有很多細節需要考慮。今天就來分享一下我的實現思路和學到的經驗。

問題分析

我們需要實現一個能夠處理加減乘除四則運算的計算器,要正確處理運算符的優先級(乘除優先于加減),同時還要處理空格和多位數字。

解決方案:中綴表達式轉后綴表達式

我選擇的方法是中綴表達式轉后綴表達式(逆波蘭表達式),然后再計算后綴表達式。這種方法雖然需要兩個步驟,但邏輯清晰,易于理解和實現。

第一步:中綴轉后綴

cpp

int calculate(string s) {vector<string> postfix;  // 存儲后綴表達式stack<string> opStack;   // 運算符棧for (int i = 0; i < s.size();) {// 跳過空格if (s[i] == ' ') {i++;continue;}// 處理數字if (isdigit(s[i])) {string num;while (i < s.size() && isdigit(s[i])) {num += s[i++];}postfix.push_back(num);} // 處理運算符else {string op(1, s[i++]);// 處理運算符優先級if (op == "+" || op == "-") {// 加減優先級最低,彈出所有運算符while (!opStack.empty()) {postfix.push_back(opStack.top());opStack.pop();}opStack.push(op);} else if (op == "*" || op == "/") {// 乘除優先級較高,只彈出同優先級的運算符while (!opStack.empty() && (opStack.top() == "*" || opStack.top() == "/")) {postfix.push_back(opStack.top());opStack.pop();}opStack.push(op);}}}// 彈出棧中剩余的所有運算符while (!opStack.empty()) {postfix.push_back(opStack.top());opStack.pop();}return evalRPN(postfix);
}

第二步:計算后綴表達式

cpp

int evalRPN(vector<string>& tokens) {stack<int> st;for (auto& e : tokens) {if (isdigit(e[0]) || (e.size() > 1 && e[0] == '-')) {st.push(stoi(e));} else {int n1 = st.top(); st.pop();int n2 = st.top(); st.pop();switch (e[0]) {case '+': st.push(n2 + n1); break;case '-': st.push(n2 - n1); break;case '*': st.push(n2 * n1); break;case '/': if (n1 == 0) throw runtime_error("Division by zero");st.push(n2 / n1); break;}}}return st.top();
}

遇到的坑和解決方案

1. 多位數字的處理

最初我忽略了數字可能有多位的情況,導致?123?被識別為三個單獨的數字?123。解決方法是在遇到數字時持續讀取直到非數字字符。

2. 運算符優先級

加減乘除的優先級不同,需要特殊處理:

  • 遇到?+?或?-?時,彈出棧中所有運算符(因為加減優先級最低)

  • 遇到?*?或?/?時,只彈出同優先級的運算符

3. 空格處理

用戶輸入可能包含空格,需要在讀取時跳過這些空格字符。

4. 除零錯誤

在除法運算時添加了除零檢查,避免程序崩潰。

寫代碼就像搭積木,有時候看似復雜的結構,拆解開來都是簡單的基礎模塊。保持思考,持續學習,共勉!

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

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

相關文章

Actix-webRust Web框架入門教程

文章目錄引言Actix-web是什么&#xff1f;準備工作你的第一個Actix-web應用理解代碼結構處理請求和響應接收請求數據返回響應中間件 - 增強你的應用狀態管理和依賴注入實用示例&#xff1a;構建RESTful API測試你的Actix-web應用部署Actix-web應用結語額外資源引言 嘿&#xf…

若依框架前端通過 nginx docker 鏡像本地運行

1. 前言 項目運行過程圖&#xff1a;對于前端項目通過命令 npm run build 打包后&#xff0c;無法直接運行。存在如下錯誤&#xff1a;可以通過配置 nginx 服務器運行前端項目解決如上問題。 2. Nginx 運行 采用 docker 鏡像的方式運行&#xff0c;docker-compose.yml 文件內容…

淺聊一下HTTP協議

在日常上網瀏覽網頁、刷視頻時&#xff0c;背后都離不開 HTTP 協議的支持。作為 Web 世界的 “交通規則”&#xff0c;它負責服務器和客戶端瀏覽器之間的數據傳輸。這篇文章就帶大家全面了解 HTTP 協議&#xff0c;從基本概念到通信細節&#xff0c;再到安全相關的 HTTPS&#…

機器人控制器開發(定位——cartographer ros2 使用2)

文章總覽 1 純定位模式 當完成建圖后&#xff0c;會生成pbstream格式的地圖文件 配置純定位模式的lua腳本 backpack_2d_localization.lua include "backpack_2d.lua"TRAJECTORY_BUILDER.pure_localization_trimmer {max_submaps_to_keep 3, } POSE_GRAPH.optimi…

《大數據之路1》筆記3:數據管理

一 元數據 1.1 元數據概述 定義&#xff1a; 元數據是關于數據的數據&#xff0c;元數據打通了源數據、數據倉庫、數據應用&#xff0c;記錄了數據從生產到消費的全部過程。元數據主要記錄數據倉庫中模型的定義、各層級間的映射關系、監控數據倉庫的數據狀態和ETL的任務運行狀態…

排序實現java

排序算法概述Java中實現排序可以通過多種方式&#xff0c;包括內置方法、自定義算法或使用第三方庫。常見的排序算法有冒泡排序、選擇排序、插入排序、快速排序、歸并排序等。使用Arrays.sort()方法對于數組排序&#xff0c;Java提供了Arrays.sort()方法&#xff0c;支持對基本…

51c大模型~合集182

我自己的原文哦~ https://blog.51cto.com/whaosoft/14174587 #LaV-CoT 超越GPT-4o&#xff0c;螞蟻集團與南洋理工大學提出&#xff1a;首個語言感知的視覺思維鏈 隨著大型視覺語言模型&#xff08;VLM&#xff09;的飛速發展&#xff0c;它們在處理復雜的視…

C++ STL之deque的使用和模擬實現

目錄 deque 核心本質與定位 與stack和queue的關系: deque的使用 deque的底層實現 deque的原理介紹 deque的缺陷 總結: deque deque文檔 : deque 翻譯: 雙端隊列 deque&#xff08;通常發音類似“deck”&#xff09;是“double-ended queue”&#xff08;雙端隊列&…

布草洗滌廠設備租賃押金原路退回系統—東方仙盟

設備租賃狀態設備管理添加設備設備收押金設備退押金在布草洗滌行業的運營版圖中&#xff0c;設備租賃是連接廠商與客戶的重要紐帶&#xff0c;而押金的收取與退還則是這一環節中關乎信任與效率的關鍵節點。未來之窗布草洗滌廠深諳此道&#xff0c;專為設備租賃業務打造的 “押金…

換源rocklinux和centos

一、Rockylinux換源&#xff0c;國外的源換成國內的源#nmcli connection modify ens33 ipv4.addresses 192.168.121.11 ipv4.gateway 192.168.121.2 ipv4.method manual ipv4.dns 114.114.114.114 connection.autoconnect yes修改地址#systemctl stop firewalld#systemctl diab…

第一部分:服務器硬件配置

目錄1.1 服務器上架與連線1.2 啟用CPU虛擬化功能&#xff08;BIOS設置&#xff09;1.3 配置RAID存儲步驟1&#xff1a;進入RAID配置界面步驟2&#xff1a;確認RAID控制器信息步驟3&#xff1a;創建系統RAID&#xff08;用于安裝ESXi&#xff09;步驟4&#xff1a;創建數據RAID&…

手搓一個 DELL EMC Unity存儲系統健康檢查清單

寫在前面對于DELL EMC存儲系統Unity的一些深度的健康檢查通過Web的Unisphere圖形化界面是做不到的&#xff0c;圖形化界面只能看到是否有告警&#xff0c;物理的東西是否有問題的&#xff0c;邏輯的Pool和LUN等是否ready&#xff0c;再深入的潛在的問題是查不到的。另外&#x…

【數據結構】二叉樹的概念

01 概念定義&#xff1a;二叉樹既然叫二叉樹&#xff0c;顧名思義即度最大為2的樹稱為二叉樹。 它的度可以為 1 也可以為 0&#xff0c;但是度最大為 2 。 一顆二叉樹是節點的一個有限集合&#xff0c;該集合&#xff1a;① 由一個根節點加上兩棵被稱為左子樹和右子樹的二叉樹組…

【RK3576】【Android14】如何在Android14下單獨編譯kernel-6.1?

單獨編譯kernel依賴如下幾個源碼&#xff1a;【交叉編譯工具鏈】prebuilts/clang/host/linux-x86/clang-r487747c【內核源碼】kernel-6.1為什么Android下編譯內核使用clang作為交叉編譯工具鏈而不是GCC&#xff1f;Android 14 選擇使用預置的 Clang 工具鏈&#xff08;如 clang…

什么是Redis的Pipeline

介紹Redis的Pipeline是一種網絡優化技術&#xff0c;在沒有Pipeline的時候&#xff0c;客戶端往redis發送請求&#xff0c;客戶端需要等到redis響應之后才能發送下一個請求。而Pipeline&#xff0c;使redis可以一次性接收多個請求。減少了通信次數&#xff0c;顯著的提高了性能…

【ElementUI el-table跨頁勾選】

一、el-table需加上refs和 row-key屬性 二、type"selection"勾選框 需加上 reserve-selection儲備選擇屬性 三、在分頁請求數據時&#xff0c;觸發 setSelected()方法 四、在 selection-change變化時保存 selectedRows <el-table ref"tables" :data&quo…

論文閱讀/博弈論/拍賣:《Truthful Auction for Cooperative Communications》

摘要&#xff1a;一方面&#xff0c;協作通信由于其在提升無線網絡容量方面的巨大潛力而日益受到關注。另一方面&#xff0c;協作通信技術的實際應用卻很少見&#xff0c;即使在一些對帶寬需求極高的應用場景中&#xff0c;系統設計者也并未采用協作通信技術來開發創新的網絡解…

系統軟中間件:連接軟件與硬件的橋梁

理解“系統軟中間件”這個術語很重要&#xff0c;它實際上是兩個緊密相關但又不同的概念的組合&#xff1a; 系統軟件中間件 嚴格來說&#xff0c;“系統軟中間件”不是一個標準的獨立術語。它通常指的是屬于系統軟件范疇的中間件&#xff0c;或者理解為作為系統軟件重要組成部…

音視頻學習(六十四):avc1 hvc1和hev1

基礎概念縮寫編碼標準FourCC說明AVC/H.264Advanced Video Codingavc1最常用的 H.264 編碼標識符&#xff0c;兼容 MP4/MOV/FMP4 等容器。HEVC/H.265High Efficiency Video Codinghvc1HEVC 視頻流在 MP4/FMP4 中常用標識符&#xff0c;要求存儲 NALU 的 VPS/SPS/PPS&#xff08;…

【WIT】編程百問一

01 什么時postman&#xff1f; Postman 是一款專門用于幫助開發人員處理 API 的工具&#xff0c;它的作用主要有以下幾個方面&#xff1a; 方便調試 API&#xff1a;就像你打電話給別人要先撥對號碼一樣&#xff0c;開發人員要讓不同的軟件系統之間通過 API 進行通信&#xff…