<?php

/**
* 四则运算(支持加、减、乘、除、小中括号)
* Class calculator
*/
class calculator {
//保留几位小数点
public $point = 2; public function __construct($point=2)
{
$this->point = $point;
} /**
* 四则运算(支持加、减、乘、除、小中括号)
* @param $str 表达式
* @throws Exception
* @author fengzi
* @date 2022-07-12 14:42
*/
function expression($str)
{
try {
$str = str_replace(' ', '', $str);
$arr = preg_split('/([\+\-\*\/\(\)\[\]])/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$numStack = [];// 存放数字
$operStack = [];// 存放运算符
$operStack[] = NULL;
for ($i = 0; $i < count($arr); $i++) { //把数字放入$numStack
if (ord($arr[$i]) >= 48 && ord($arr[$i]) <= 57) {
array_push($numStack, $arr[$i]);
continue;
} switch ($arr[$i]) {
case '+':
case '-':
$arrLen = count($operStack);
while ($operStack[$arrLen - 1] === '*' || $operStack[$arrLen - 1] === '/' || $operStack[$arrLen - 1] === '-') {
$this->compute($numStack, $operStack);
$arrLen--;
}
array_push($operStack, $arr[$i]);
break;
case '*':
$arrLen = count($operStack);
while ($operStack[$arrLen - 1] === '/') {
$this->compute($numStack, $operStack);
$arrLen--;
}
array_push($operStack, $arr[$i]);
break;
case '/':
case '(':
case '[':
array_push($operStack, $arr[$i]);
break;
case ']':
$arrLen = count($operStack);
while ($operStack[$arrLen - 1] !== '[') {
$this->compute($numStack, $operStack);
$arrLen--;
}
array_pop($operStack);
break;
case ')':
$arrLen = count($operStack);
while ($operStack[$arrLen - 1] !== '(') {
$this->compute($numStack, $operStack);
$arrLen--;
}
array_pop($operStack);
break;
default:
throw new \Exception("不支持的运算符", 1);
break;
}
} $arrLen = count($operStack);
while ($operStack[$arrLen - 1] !== NULL) {
$this->compute($numStack, $operStack);
$arrLen--;
} return array_pop($numStack);
} catch (Exception $e) {
return $e->getMessage();
}
} /**
* 数字栈长度减一,运算符栈长度减一
* @param $numStack 存放数字
* @param $operStack 存放运算符
* @throws Exception
* @author fengzi
* @date 2022-07-12 14:44
*/
function compute(&$numStack, &$operStack){
$num = array_pop($numStack); //运算结果四舍五入
$caseKey = array_pop($operStack);
switch ($caseKey) {
case '*':
array_push($numStack, number_format(array_pop($numStack) * $num, $this->point, '.', ''));
break;
case '/':
array_push($numStack, number_format(array_pop($numStack) / $num, $this->point, '.', ''));
break;
case '+':
array_push($numStack, number_format(array_pop($numStack) + $num, $this->point, '.', ''));
break;
case '-':
array_push($numStack, number_format(array_pop($numStack) - $num, $this->point, '.', ''));
break;
case '(':
case '[':
throw new \Exception("不匹配的{$caseKey}");
break;
default:
throw new \Exception("未知符号");
break;
}
}
}

  

PHP四则运算类(支持加、减、乘、除、小中括号)的更多相关文章

  1. Java类的加载的一个小问题

    前言 之前写了一篇文章专门介绍了一下类的加载和对象的创建流程,然后收到了一个博友的疑问,觉得蛮好的,在这里和大家分享下. 博文地址:[Java基础]Java类的加载和对象创建流程的分析 疑问 类在加载 ...

  2. Java对日期Date类进行加减运算,年份加减,月份加减

      import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date; public class Da ...

  3. 【转】Java对日期Date类进行加减运算,年份加减,月份加减

    import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date; public class Date ...

  4. 日期类的加减及java中所以日期类的操作算法大全

    1.计算某一月份的最大天数 1Calendar time=Calendar.getInstance();2time.clear();3time.set(Calendar.YEAR,year); //y ...

  5. 转 Java对日期Date类进行加减运算一二三

    请移步,https://blog.csdn.net/hacker_lees/article/details/74351838 ,感谢博主分享

  6. JAVA生成问答式验证码图片,支持加减算法

    原文:http://liuguihua0823.iteye.com/blog/1511355 import java.awt.Color; import java.awt.Font; import j ...

  7. Java对日期Date类进行加减运算一二三

    转载大神 https://blog.csdn.net/hacker_lees/article/details/74351838

  8. js实现文本框支持加减运算的方法

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/T ...

  9. Java初学者作业——定义一个计算器类, 实现计算器类中加、 减、 乘、 除的运算方法, 每个方法能够接收2个参数。

    返回本章节 返回作业目录 需求说明: 定义一个计算器类, 实现计算器类中加. 减. 乘. 除的运算方法, 每个方法能够接收2个参数. 实现思路: 定义计算器类. 定义计算器类中加.减.乘.除的方法. ...

  10. 大一C语言学习笔记(10)---编程篇--制作简易计算器,支持加,减,乘,除,取余运算,要求 0 bug

    博主自开学初就一直在努力为自己的未来寻找学习方向,学习编程嘛,尽量还是要抱大腿的,所以我就加入了我们学校的智能设备研究所,别的不说,那的学长们看起来是真的很靠谱,学长们的学习氛围也超级浓厚,所以我就打 ...

随机推荐

  1. 微信小程序-页面跳转navigator组件

    官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/route.html 在官方文档当中有提到一 ...

  2. go中string是如何实现的呢

    go中string是如何实现的呢 前言 实现 go语言中的string是不可变的 []byte转string string转[]byte 字符串的拼接 +方式进行拼接 fmt 拼接 Join 拼接 b ...

  3. HarmonyOS实战[二]—超级详细的原子化服务体验[可编辑的卡片交互]快来尝试吧

    相关文章: HarmonyOS实战[一]--原理概念介绍安装:基础篇 [本文正在参与"有奖征文|HarmoneyOS征文大赛"活动] 1.创建HarmonyOS应用 选择Java程 ...

  4. C++ STL 标准模板库(排序/集合/适配器)算法

    C++ 标准模板库STL,是一个使用模板技术实现的通用程序库,该库由容器container,算法algorithm,迭代器iterator,容器和算法之间通过迭代器进行无缝连接,其中所包含的数据结构都 ...

  5. UDP通信 [补档-2023-07-22]

    UDP通信 6-1 简介 ​ UDP通信是面向无链接的,不稳定,不可靠,不安全的一种通信方式.TCP在通信前发送方会向接收方进行三次握手链接,然后确认双方链接后才会进行数据传输,最后四次挥手保证链接关 ...

  6. requests模块的高级应用

    requests抓取数据报错 - HttpConnectinPool: - 原因: - 1.短时间内发起了高频的请求导致ip被禁 - 2.http连接池中的连接资源被耗尽 - 解决: - 1.代理 - ...

  7. Qt信号槽原理

    1.说明 使用Qt已经好几年了,一直以为自己懂Qt,熟悉Qt,使用起来很是熟练,无论什么项目,都喜欢用Qt编写.但真正去看Qt的源码,去理解Qt的思想也就近两年的事. 本次就着重介绍一下Qt的核心功能 ...

  8. Advanced Installer设置安装最后一步启动软件

    左侧用户界面中选择对话框-ExitDialog 在完成操作项中勾选"安装结束时启动应用程序",在弹出的对话框中选择需要启动的exe文件

  9. 【栈和队列】纯C实现栈和队列以及其基本操作-宝藏级别数据结构教程【保姆级别详细教学】

    [栈和队列]栈和队列的C语言实现-宝藏级别数据结构教程-超详细的注释和解释 先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记 ...

  10. (数据科学学习手札158)基于martin为在线地图快速构建精灵图服务

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,martin作为快速发展中的新 ...