实现一个计算机

图片:

实现代码: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            padding: 20px;
            font-family: Arial;
        }

        .calc-wrap {
            width: 300px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }


        .calc-operation {
            width: 100%;
            border-collapse: collapse;
        }

        .calc-in-out {
            width: 100%;
            padding: 10px 20px;
            text-align: right;
            box-sizing: border-box;
            background-color: rgba(250, 250, 250, .9);
        }
        .calc-in-out p {
            overflow: hidden;
            margin: 5px;
            width: 100%;
        }
        .calc-history {
            margin-left: -20px;
            font-size: 18px;
            color: #bbb;
            border-bottom: 1px dotted #ddf;
            min-height: 23px;
        }

        .calc-in,
        .calc-out {
            font-size: 20px;
            color: #888;
            line-height: 39px;
            min-height: 39px;
        }

        .calc-in {
            color: #888;
        }
        .calc-out {
            color: #ccc;
        }

        .calc-in.active,
        .calc-out.active {
            font-size: 34px;
            color: #666;
        }

        .calc-operation td {
            padding: 10px;
            width: 25%;
            text-align: center;
            border: 1px solid #ddd;
            font-size: 26px;
            color: #888;
            cursor: pointer;
        }

        .calc-operation td:active {
            background-color: #ddd;
        }

        .calc-operation .cls {
            color: #ee8956;
        }


    </style>
    <script src="../plug/jquery-3.2.0.min.js"></script>
</head>
<body>
<h5>计算计算</h5>
<!-- 计算器 -->
<div class="calc-wrap">
    <div class="calc-in-out">
        <!-- 上一条运算记录 -->
        <p class="calc-history" title=""></p>
        <!-- 输入的数据 -->
        <p class="calc-in"></p>
        <!-- 输出的运算结果 -->
        <p class="calc-out active"></p>
    </div>
    <table class="calc-operation">
        <thead></thead>
        <tbody>
        <tr>
            <td data-ac="cls" class="cls">C</td>
            <td data-ac="del">&larr;</td>
            <td data-ac="sq">x<sup>2</sup></td>
            <td data-ac="mul">&times;</td>
        </tr>
        <tr>
            <td data-val="7">7</td>
            <td data-val="8">8</td>
            <td data-val="9">9</td>
            <td data-ac="div">&divide;</td>
        </tr>
        <tr>
            <td data-val="4">4</td>
            <td data-val="5">5</td>
            <td data-val="6">6</td>
            <td data-ac="plus">+</td>
        </tr>
        <tr>
            <td data-val="1">1</td>
            <td data-val="2">2</td>
            <td data-val="3">3</td>
            <td data-ac="minus">-</td>
        </tr>
        <td data-ac="per">%</td>
        <td data-val="0">0</td>
        <td data-ac="dot">.</td>
        <td data-ac="eq" class="eq">=</td>
        </tbody>
    </table>
</div>
</body>
<script>
    $(function() {

        function Calculator($dom) {
            this.$dom = $($dom);
            // 历史运算
            this.$history = this.$dom.find('.calc-history');
            // 输入区
            this.$in = this.$dom.find('.calc-in');
            // 输出区
            this.$out = this.$dom.find('.calc-out');
            this.$operation = this.$dom.find('.calc-operation');

            // 运算符映射
            this.op = {
                'plus': '+',
                'minus': '-',
                'mul': '*',
                'div': '/'
            };
            this.opArr = ['+', '-', '*', '/'];

            // 中缀表达式
            this.infix = [];
            // 后缀表达式
            this.suffix = [];
            // 后缀表达式运算结果集
            this.result = [];
            // 存储最近的值
            this.lastVal = 0;
            // 当前已经计算等于完成
            this.calcDone = false;
            // 当前正在进行小数点点(.)相关值的修正
            this.curDot = false;

            this.init();
        }

        Calculator.prototype = {
            constructor: Calculator,
            // 初始化
            init: function() {
                this.bindEvent();
            },
            // 绑定事件
            bindEvent: function() {
                var that = this;

                that.$operation.on('click', function(e) {
                    e = e || window.event;
                    var elem = e.target || e.srcElement,
                        val,
                        action;

                    if (elem.tagName === 'TD') {
                        val = elem.getAttribute('data-val') || elem.getAttribute('data-ac');
                        // 数字:0-9
                        if (!isNaN(parseInt(val, 10))) {
                            // 构建中缀表达式并显示
                            var infixRe = that.buildInfix(parseInt(val, 10), 'add');
                            that.$in.text(infixRe.join('')).addClass('active');

                            that.calculate();

                            return;
                        }

                        action = val;

                        // 操作:清除、删除、计算等于
                        if (['cls', 'del', 'eq'].indexOf(action) !== -1) {
                            if (!that.infix.length) {
                                return;
                            }

                            // 清空数据
                            if (action === 'cls' || (action === 'del' && that.calcDone)) {
                                that.$in.text('');
                                that.$out.text('');

                                that.resetData();
                            }
                            // 清除
                            else if (action === 'del') {
                                // 重新构建中缀表达式
                                var infixRe = that.buildInfix(that.op[action], 'del');
                                that.$in.text(infixRe.join('')).addClass('active');

                                that.calculate();

                            }
                            // 等于
                            else if (action === 'eq') {
                                that.calculate('eq');

                            }
                        }
                        // 预运算:百分比、小数点、平方
                        else if (['per', 'dot', 'sq'].indexOf(action) !== -1) {
                            if (!that.infix.length || that.isOp(that.lastVal)) {
                                return;
                            }

                            if (action === 'per') {
                                that.lastVal /= 100;
                            } else if (action === 'sq') {
                                that.lastVal *= that.lastVal;
                            } else if (action === 'dot') {
                                // that.curDot = true;
                            }

                            // 重新构建中缀表达式
                            var infixRe = that.buildInfix(that.lastVal, 'change');
                            that.$in.text(infixRe.join('')).addClass('active');

                            that.calculate();
                        }
                        // 运算符:+ - * /
                        else if (that.isOp(that.op[action])) {
                            if (!that.infix.length && (that.op[action] === '*' || that.op[action] === '/')) {
                                return;
                            }

                            var infixRe = that.buildInfix(that.op[action], 'add');
                            that.$in.text(infixRe.join('')).addClass('active');
                        }
                    }
                });
            },

            resetData: function() {
                this.infix = [];
                this.suffix = [];
                this.result = [];
                this.lastVal = 0;
                this.curDot = false;
            },

            // 构建中缀表达式
            buildInfix: function(val, type) {
                // 直接的点击等于运算之后,
                if (this.calcDone) {
                    this.calcDone = false;
                    // 再点击数字,则进行新的运算
                    if (!this.isOp(val)) {
                        this.resetData();
                    }
                    // 再点击运算符,则使用当前的结果值继续进行运算
                    else {
                        var re = this.result[0];
                        this.resetData();
                        this.infix.push(re);
                    }

                }

                var newVal;

                // 删除操作
                if (type === 'del') {
                    newVal = this.infix.pop();
                    // 删除末尾一位数
                    newVal = Math.floor(newVal / 10);
                    if (newVal) {
                        this.infix.push(newVal);
                    }

                    this.lastVal = this.infix[this.infix.length - 1];
                    return this.infix;
                }
                // 添加操作,首先得判断运算符是否重复
                else if (type === 'add') {
                    // 两个连续的运算符
                    if (this.isOp(val) && this.isOp(this.lastVal)) {
                        return this.infix;
                    }
                    // 两个连续的数字
                    else if (!this.isOp(val) && !this.isOp(this.lastVal)) {
                        newVal = this.lastVal * 10 + val;
                        this.infix.pop();
                        this.infix.push(this.lastVal = newVal);

                        return this.infix;
                    }
                    // 首个数字正负数
                    if (!this.isOp(val) && this.infix.length === 1 && (this.lastVal === '+' || this.lastVal === '-')) {
                        newVal = this.lastVal === '+' ? val : 0 - val;
                        this.infix.pop();
                        this.infix.push(this.lastVal = newVal);

                        return this.infix;
                    }

                    // TODO: 小数点运算
                    //     if (this.isOp(val)) {
                    //         this.curDot = false;
                    //     }

                    //     // 小数点
                    //     if (this.curDot) {
                    //         var dotLen = 0;
                    //         newVal = this.infix.pop();
                    //         dotLen = newVal.toString().split('.');
                    //         dotLen = dotLen[1] ? dotLen[1].length : 0;

                    //         newVal +=  val / Math.pow(10, dotLen + 1);
                    //         // 修正小数点运算精确值
                    //         newVal = parseFloat(newVal.toFixed(dotLen + 1));

                    //         this.infix.push(this.lastVal = newVal);
                    //         return this.infix;
                    //     }

                    this.infix.push(this.lastVal = val);
                    return this.infix;
                }

                // 更改操作,比如%的预运算
                else if (type === 'change') {
                    this.infix.pop();
                    this.infix.push(this.lastVal = val);

                    return this.infix;
                }

            },
            // 判断是否为运算符
            isOp: function(op) {
                return op && this.opArr.indexOf(op) !== -1;
            },
            // 判断运算符优先级
            priorHigher: function(a, b) {
                return (a === '+' || a === '-') && (b === '*' || b === '/');
            },
            // 进行运算符的运算
            opCalc: function(b, op, a) {
                return op === '+'
                    ? a + b
                    : op === '-'
                        ? a - b
                        : op === '*'
                            ? a * b
                            : op === '/'
                                ? a / b
                                : 0;
            },
            // 即时得进行运算
            calculate: function(type) {
                this.infix2Suffix();
                var suffixRe = this.calcSuffix();

                if (suffixRe) {
                    this.$out.text('=' + suffixRe)
                        .attr('title', suffixRe)
                        .removeClass('active');

                    // 如果是直接显示地进行等于运算
                    if (type === 'eq') {
                        this.$in.removeClass('active');
                        this.$out.addClass('active');
                        // 设置标记:当前已经显示地进行计算
                        this.calcDone = true;
                        this.lastVal = suffixRe;
                        // 设置历史记录
                        var history = this.infix.join('') + ' = ' + suffixRe;
                        this.$history.text(history).attr('title', history);
                    }

                }
            },

            // 中缀表达式转后缀
            infix2Suffix: function() {
                var temp = [];
                this.suffix = [];

                for (var i = 0; i < this.infix.length; i++) {
                    // 数值,直接压入
                    if (!this.isOp(this.infix[i])) {
                        this.suffix.push(this.infix[i]);
                    }
                    else {
                        if (!temp.length) {
                            temp.push(this.infix[i]);
                        }
                        else {
                            var opTop = temp[temp.length - 1];
                            // 循环判断运算符优先级,将运算符较高的压入后缀表达式
                            if (!this.priorHigher(opTop, this.infix[i])) {
                                while (temp.length && !this.priorHigher(opTop, this.infix[i])) {
                                    this.suffix.push(temp.pop());
                                    opTop = temp[temp.length - 1];
                                }
                            }
                            // 将当前运算符也压入后缀表达式
                            temp.push(this.infix[i]);
                        }
                    }
                }
                // 将剩余运算符号压入
                while (temp.length) {
                    this.suffix.push(temp.pop());
                }
            },

            // 后缀表达式计算
            calcSuffix: function() {
                this.result = [];

                for (var i = 0; i < this.suffix.length; i++) {
                    // 数值,直接压入结果集
                    if (!this.isOp(this.suffix[i])) {
                        this.result.push(this.suffix[i]);
                    }
                    // 运算符,从结果集中取出两项进行运算,并将运算结果置入结果集合
                    else {
                        this.result.push(this.opCalc(this.result.pop(), this.suffix[i], this.result.pop()));
                    }
                }
                // 此时结果集中只有一个值,即为结果
                return this.result[0];
            }
        };

        new Calculator('.calc-wrap');
    });



</script>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/180587.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Threejs_13 聚光灯和点光源的使用

聚光灯就如同手电筒一样&#xff0c;点光源就如同一个电灯泡甚至是萤火虫那样。如何使用他们呢&#xff1f; 我们还是一样&#xff0c;先做一个小球和一个平面&#xff0c;用来展示光线。并且加入基本的环境光。 // 做一个球体 const SphereGeometry new THREE.SphereGeomet…

Vue中使用Echarts实现数据可视化

文章目录 引言一、安装Echarts二、引入Echarts三、创建图表容器四、初始化Echarts实例五、配置图表选项和数据六、实现图表更新七、Vue实例代码结语我是将军&#xff0c;我一直都在&#xff0c;。&#xff01; 引言 接着上一篇内容&#xff0c;我将继续分享有关数据可视化的相…

docker安装mysql挂着目录和mysql备份和恢复

第一&#xff0c;镜像拉取&#xff0c;运行镜像并挂载目录&#xff0c;尝试挂bin下&#xff0c;启动不了&#xff0c;不知为啥 docker run --privilegedtrue -itd --namevmysql -p 3306:3306 -v /home/vmysql:/home/vmysql -e MYSQL_ROOT_PASSWORD123456 mysql&#xff08;图…

为何设计师都在用这个原型样机资源网站?

谈论原型样机素材模板&#xff0c;这个话题对设计师来说如同老朋友一般熟悉。设计师们在创作完毕后&#xff0c;为了更淋漓尽致地展示他们的设计成果&#xff0c;通常会将其放置在真实的样机素材模板中。这种原型样机素材可以让设计作品迅速且清晰地呈现在真实环境中。找到一个…

福州大学《嵌入式系统综合设计》实验五:图像裁剪及尺寸变换

一、实验目的 在深度学习中&#xff0c;往往需要从一张大图中裁剪出一张张小图&#xff0c;以便适应网络输入图像的尺寸&#xff0c;这可以通过bmcv_image_crop函数实现。 实践中&#xff0c;经常需要对输入图像的尺寸进行调整&#xff0c;以适用于网络输入图片尺寸&#xff0…

计网(复习自用)

计算机网络 1.概述 1.1概念 含义 计算机网络&#xff1a;是一个将分散的。具有独立功能的计算机系统&#xff0c;通过通信设备和线路连接起来&#xff0c;由功能完善的软件实现资源共享和信息传递的系统。 简单点说&#xff0c;计算机网络是互联的&#xff0c;自治的计算机集…

低成本打造便携式无线网络攻防学习环境

1.摘要 一直以来, 无线网络安全问题与大众的个人隐私息息相关, 例如: 为了节省流量, 连接到一个看似安全的免费WiFi, 在使用过程中泄露自己的各类密码信息甚至银行卡账号密码信息。随着家用智能电器的普及, 家中的各类智能设备连入家里的无线网络, 却突然失灵, 甚至无法正常连…

碳化硅MOS/超结MOS在直流充电桩上的应用-REASUNOS瑞森半导体

一、前言 直流充电桩是新能源汽车直流充电桩的简称&#xff0c;一般也被叫做“快充”。直流充电桩一般与交流电网连接&#xff0c;可作为非车载电动汽车的动力补充&#xff0c;是一种直流工作电源的电源控制装置&#xff0c;可以提供充足的电量&#xff0c;输出电压和电流可以…

Windows日常故障自我排查:用工具eventvwr.msc(事件查看器)分析问题故障

windows故障排查方法一&#xff1a; 工具用法 系统故障问题时&#xff0c;找不到解决方法 首先&#xff0c; 在搜索栏输入&#xff1a; 事件查看器(eventvwr.msc) 打开程序 根据程序找到程序运行的LOG 根据程序Operational筛选出错误日志&#xff1a; 日志中找错误原因&…

itext - PDF模板套打

项目需求&#xff1a;获取列表数据之后直接将数据生成一个pdf。因此需要使用到 itext 对pdf进行直接操作。 环境配置 需要为pdf添加文字域&#xff0c;因此需要安装Adobe Acrobat 准备一个空的PDF文件&#xff0c;如果有现成的模板更好 依赖配置&#xff0c;我们使用itext的7版…

揭示卡尔曼滤波器的威力

一、说明 作为一名数据科学家&#xff0c;我们偶尔会遇到需要对趋势进行建模以预测未来值的情况。虽然人们倾向于关注基于统计或机器学习的算法&#xff0c;但我在这里提出一个不同的选择&#xff1a;卡尔曼滤波器&#xff08;KF&#xff09;。 1960 年代初期&#xff0c;Rudol…

基于H1ve一分钟搭好CTF靶场

写在前面 ◉ ‿ ◉ 上一篇文章给大家详细介绍了基于H1ve搭建CTF靶场&#xff0c;以及过程中可能遇到的报错及解决方法&#xff0c;那么这篇文章&#xff0c;我总结了一下&#xff0c;将不会遇到报错的方法给到大家&#xff0c;但是前提是你的服务器最好是一个全新的哦~~~ 我…

小程序订阅消息

wx.requestSubscribeMessage({tmplIds: [2IdqlWrqSbjAurzIuW8imeK-ftS8gbhYdZ0icdE],success(res) {console.log(res);// 处理用户授权结果},fail(err) {console.error(err);// 处理授权请求失败}});

淡入淡出transition: right 1s

transition: right 1s; //重点直接改变right值 操作过快 这里用该方法实现1s内淡入淡出 达到效果目标

20230511 Windows Ubuntu vscode remote-ssh 连接配置

参考 &#xff1a; VSCode SSH 连接远程ubuntu Linux 主机 VSCode通过Remote SSH扩展连接到内网Ubuntu主机 Ubuntu 安装 sudo apt-get install openssh-server vscode: 安装remote-ssh 插件 连接到服务器IP 免密登录的公钥密钥传递用filezillaUbuntu 和 Windows 文件互传 …

ios(swiftui) 画中画

一、环境 要实现画中画 ios系统必须是 iOS14 本文开发环境 xcode14.2 二、权限配置 在项目导航器中单击项目&#xff0c;然后单击Signing & Capabilities。单击 Capabilit搜索Background Modes&#xff0c;然后双击将其添加为功能。在新添加的Background Modes部分&a…

chatglm3部署使用

chatglm3部署使用 1.部署2.使用3.接入微信4.vue前端 1.部署 1.首先去github下载chatglm3代码。Huggingface下载模型一直失败&#xff0c;所以用阿里的魔塔社区下载。 git clone https://github.com/THUDM/ChatGLM3.git git clone https://www.modelscope.cn/ZhipuAI/chatglm3…

SpringMVC 基础知识

学习目标 掌握基于 SpringMVC 获取请求参数与响应 json 数据操作熟练应用基于 REST 风格的请求路径设置与参数传递能够根据实际业务建立前后端开发通信协议并进行实现基于 SSM 整合技术开发任意业务模块功能 1 SpringMVC 简介 1.1 概述 1.1.1 web程序开发流程 【执行过程】…

Hook+jsdom 解决cookie逆向

前言 记录下如何破cookie逆向 目标 目标网址:https://q.10jqka.com.cn/ 目标接口:http://q.10jqka.com.cn/index/index/board/all/field/zdf/order/desc/page/2/ajax/1/ 对抗:cookie反爬虫处理,关键字v,如图 解决步骤 1、JS中关键字查找 如上,我们找到了关键字 v,…

etoken是什么意思,有什么作用?

EToken是一种数字货币&#xff0c;它是由以太坊区块链平台发行的智能合约&#xff0c;旨在为以太坊生态系统提供一种安全、可靠、去中心化的交易媒介。EToken具有多种作用&#xff0c;下面将详细介绍。 一、EToken的定义和发行 EToken是由以太坊智能合约创建的数字货币&#xf…