<?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. C语言输出键盘

    使用printf()函数输出样式 #include <stdio.h> int main() { printf("┌───┬───┬───┬───┬───┬───┬───┬─── ...

  2. MySQL【五】与python交互

    1.安装pymysql 安装pymysql pip install pymysql 2.游标(cursor)的使用 cursor,就是一个标识,用来标识数据可以理解成数组中的下标  . 一.声明一个游 ...

  3. 【二】Latex入门使用、常见指令

    参考链接:https://blog.csdn.net/cocoonyang/article/details/78036326 \documentclass[12pt, a4paper]{article ...

  4. 【Trento】遥感图像数据集提供下载

    遥感图像处理学习(11)之Trento数据集 前言 遥感系列第11篇.遥感图像处理方向的学习者可以参考或者复刻 本文初编辑于2024年1月18日 2024年1月25日搬运至本人博客园平台 最近在复现论 ...

  5. ESXi6.5导入虚拟机提示缺少所需的磁盘镜像

    环境 esxi6.7 错误提示 解决方案 原因:这是因为导出虚拟机的时候,没有把"CD/DVD驱动器"删掉,在导入的时候,找不到这个磁盘映像. 编辑.ovf文件,找到ovf:hre ...

  6. 在K8S中,节点故障驱逐pod过程时间怎么定义?

    在Kubernetes中,节点故障驱逐Pod的过程涉及多个参数和组件的相互作用.以下是该过程的简要概述: 默认设置:在默认配置下,节点故障时,工作负载的调度周期约为6分钟. 关键参数: node-mo ...

  7. P9816 少项式复合幂 题解

    题目链接:少项式复合幂 注意到题目的模并不是很大,我们考虑两个核心的性质. \(f(f(x)) \bmod p=f(f(x) \bmod p) \bmod p\),证明直接代入 \(f(x)\) 进去 ...

  8. 练习(Java):将一个数转换为16进制;获得多位数的各个位上的数

    //将一个数转换为十六进制 int num = 60; int i1 = num % 16; int i2 = num % (16*16) / 16; int i3 = num % (16*16*16 ...

  9. 案例:OGG目标端进程ABENDED处理

    源端环境:RHEL 6.5 + Oracle 11.2.0.4 RAC + OGG 19.1.0.0.4 目标端环境:RHEL 7.6 + Oracle 19.3 + OGG 19.1.0.0.4 故 ...

  10. 数学问题,2的n次方 - 1 是怎么来的? 通常用作计算数值