<?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. .net Core IsDefined、GetValues、HasFlag 使用

    IsDefined可以用于判断传入的单个值是否属于该枚举 GetValues检索指定枚举中常量值的数组 HasFlag 可以用于判断传入的多个值是否属于该枚举 先来个例子: public enum B ...

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

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

  3. [转发]MySQL安装配置教程(超级详细、保姆级)

    MySQL安装配置教程(超级详细.保姆级)_SoloVersion的博客-CSDN博客_mysql安装配置教程一. 下载MySQLMysql官网下载地址https://downloads.mysql. ...

  4. 《熬夜整理》保姆级系列教程-玩转Wireshark抓包神器教程(1)-初识Wireshark

    1.简介 前边已经介绍过两款抓包工具,应该是够用了,也能够处理在日常工作中遇到的问题了,但是还是有人留言让宏哥要讲解讲解Wireshark这一款抓包工具,说实话宏哥之前也没有用过这款工具,只能边研究边 ...

  5. Swift中UITableViewDiffableDataSource的使用

    在 iOS 13 中 Apple 为 UITableView 和 UICollectionView 引入了 DiffableDataSource, 让开发者可以更简单高效的实现 UITableView ...

  6. 4、Web前端学习规划:JavaScript - 学习规划系列文章

    JavaScript作为Web前端里的第3重要的语言,笔者认为该重点进行学习.因为JavaScript衍生出来的框架和类库有不少,而且很强大.所以JavaScript的学习要抓好重点,在基本的语法及应 ...

  7. 基于 Gurobi 的纸浆运载船顺序装卸决策建模求解|Gurobi优化应用

    Pulp-Carrier-Loading-Optimization-with-Gurobi 基于 Gurobi 的纸浆运载船顺序装卸决策建模求解.中山大学智能工程学院<运筹学>课程期末建模 ...

  8. php获取服务器操作系统等信息

    php获取服务器操作系统等信息 获取请求页面时通信协议的名称和版本: $_SERVER['SERVER_PROTOCOL'] 例如,"HTTP/1.0". PHP程式版本:< ...

  9. 基于Hyper-V搭建免费桌面云

    Hyper-V 是 Microsoft 的硬件虚拟化产品. 它用于创建并运行计算机的软件版本,称为"虚拟机". 每个虚拟机都像一台完整的计算机一样运行操作系统和程序. 如果需要计算 ...

  10. Java并发(六)----线程start、run、state方法

    1.start 与 run 调用 run public static void main(String[] args) {    Thread t1 = new Thread("t1&quo ...