<?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. golang uuid库介绍

    简介: 在现代软件开发中,全球唯一标识符(UUID)在许多场景中发挥着重要的作用.UUID是一种128位的唯一标识符,它能够保证在全球范围内不重复.在Go语言中,我们可以使用第三方库github.co ...

  2. TienChin 活动管理-搜索活动

    ActivityController @PreAuthorize("hasPermission('tienchin:activity:list')") @GetMapping(&q ...

  3. 9.9 Windows驱动开发:内核远程线程实现DLL注入

    在笔者上一篇文章<内核RIP劫持实现DLL注入>介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过NtCreateThreadEx这个内核函数实 ...

  4. 外部文件使用django的models

    #外部文件使用django的models,需要配置django环境 import os if __name__ == '__main__': os.environ.setdefault("D ...

  5. 从此告别涂硅脂 利民推出新款CPU固态导热硅脂片:一片26.9元

    利民(Thermalright)近日推出了新款Heilos CPU固态导热硅脂片,其中Intel版为26.9元,AMD版售价29.9元. 以往向CPU上涂硅脂,需要先挤一粒绿豆大小的硅脂,然后用塑料片 ...

  6. PAC主成分分析__784手写特征案例

    from sklearn.neighbors import KNeighborsClassifier as KNN from sklearn.decomposition import PCA from ...

  7. CF1010C Border 题解

    题目传送门 前置知识 最大公约数 | 裴蜀定理 简化题意 给定一个长度为 \(n\) 的序列 \(a\),求 \((\sum\limits_{i=1}^{n}d_ia_i) \bmod k\) 一共会 ...

  8. Python 中获取文件名

    Python 获取文件名import osimport sys # ①获取当前文件名os.path.basename(__file__)# ②获取程序启动文件名os.path.basename(sys ...

  9. Uniapp+Nodejs实现外卖App项目1-项目介绍

    项目介绍 本项目采用uniapp和nodejs(数据接口).mongodb等技术实现了一个类似美团外卖的简易APP.项目主要目的是为了快速上手,如何快速使用uniapp开发一个app项目,同时掌握一些 ...

  10. Java使用ConcurrentHashMap实现简单的内存式缓存

    需求说明: 实际项目中我打算把用户和组织信息放到缓存中,基于此提出以下几点需求: 1.数据存储在内存中: 2.允许以键值对的方式存储对象类数据并带有过期策略: 3.不限制内存使用,但cache也不能给 ...