返回顶部
首页 > 资讯 > 精选 >JavaScript如何实现计算器的四则运算功能
  • 322
分享到

JavaScript如何实现计算器的四则运算功能

2023-06-29 02:06:34 322人浏览 泡泡鱼
摘要

小编给大家分享一下javascript如何实现计算器的四则运算功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、需求 + 最终实现注:只是前端实现1. 需求需

小编给大家分享一下javascript如何实现计算器的四则运算功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

一、需求 + 最终实现

注:只是前端实现

1. 需求

需求来源是因为有一个做嵌入式 C/C++的基友做了一个远程计算器。 需求是要求支持输入一个四则混合运算公式的字符串,返回计算后的结果。

想看看用 C/c++封装过的 JavaScript 如果要实现这样一个功能最终效果(文章后我会讨论这两种实现思路,还望各位看官可以提出一些优化方案以及建议之类的~)。

2. 说明:利用了字符串(split、replace)和数组(splice)的方法。

主要是用到字符串切分为数组的方法 split、以及数组中插入删除的方法 splice。 字符串正则 replace 方法是考虑到用户的输入习惯可能有所不同,例如 1+2*3/4 与 3 * 7 + 229。

支持:

  • 基础四则运算 3+6*5/6-3;

  • 小数四则运算 3.14 + 6 * 5 / 6 - 3.5;

  • 高位四则运算 99 * 94 - 6.35 + 100 / 1024;

  • 多次四则运算 3 * 3 + 3 * 16 - 7 - 5 + 4 / 2 + 22;

  • 以上综合

不支持:

  • 带括号的运算 1 * (2 - 3);

  • 其他数学运算

3. 代码实现

const calculator = (str) => {  // 定义添加字符函数  const add = (arr, symbol) => {    let length = arr.length;    while (length > 1) {      arr.splice(length - 1, 0, symbol); // 在每一项后面添加对应的运算符      length--;    }    return arr; // 目的是得到一个改变长度的数组  }  const array = add(str.replace(/\s*/g,"").split('+'), '+').map(it => add(it.split('-'), '-').map(it => add(it.split('*'), '*').map(it => add(it.split('/'), '/')))).flat(3);;  // 先运算乘除法  ['*', '/'].map(it => {    while (array.includes(it)) {      const index = array.findIndex(o => o === it);      index > 0 && it === '*' ? array.splice(index - 1, 3, (Number(array[index - 1]) * Number(array[index + 1]))) : array.splice(index - 1, 3, (Number(array[index - 1]) / Number(array[index + 1])));    }  })  // 再执行加减法,即从左至右的计算  while (array.length > 1) {    array[1] === '+' ? array.splice(0, 3, (Number(array[0]) + Number(array[2]))) : array.splice(0, 3, (Number(array[0]) - Number(array[2])));  }  return Number(array[0]).toFixed(2);}

如果对 es6 语法还算熟悉的话,应该可以轻松阅读代码的。 想必你也注意到了,这也是其中令我比较纠结的:在日常开发中,是否该经常写一些面条代码呢?

二、实现步骤

(轻松理解的大佬可以直接跳到:步骤3)

实现最基础的加减乘除

支持高位数的运算

支持多次的运算

支持...

如果是初学者,建议跟着敲一下过程(或者 f12 验证 + 调试),编程能力某种角度下一定是建立在代码量之下的。

1. 版本一:实现基础加减乘除

// 版本一const calculator = ((str) => {  // 定义最基础的加减乘除  const add = (a, b) => a + b;  const sub = (a, b) => a - b;  const mul = (a, b) => a * b;  const div = (a, b) => a / b;  // 将输入的字符串处理为 数组  const array = str.split('');  // **【处理基本四则运算】  ['*', '/', '+', '-'].map(it => {    const index = array.findIndex(o => o === it);    if (index > 0) {      switch (it) {        case '*':          array[index + 1] = mul(array[index - 1], array[index + 1]);          break;        case '/':          array[index + 1] = div(array[index - 1], array[index + 1]);          break;        case '+':          array[index + 1] = add(Number(array[index - 1]), Number(array[index + 1]));          break;        case '-':          array[index + 1] = sub(Number(array[index - 1]), Number(array[index + 1]));          break;      }      array.splice(index - 1, 2)    }  })  // return array[0];  console.log('返回值:', array[0]);})('3+6*5/6-3')// 返回值: 5

这样就实现了一个四则混合运算的计算器!

但是这个计算器很鸡肋,只是一个最基础的功能上的实现。即:只可以运行一位数数字的加减乘除混合运算。

其实第一步的想法是,利用数组的性质,通过操作数组来操作单次的四则运算。其中数组的遍历,我优先 *, / 法,紧接着是 +,- 法。 这其实是有问题的,乘除法在实际运算中的优先级并不明显,可以说是不怎么影响运算的结果(在文章最后一个版本实现涉及到性能上的讨论时会详谈),但是加减法就会有影响了:必须是从左至右的实现,否则影响运算的结果(这里不多赘述)。

【处理基本四则运算】

首先处理字符串为数组 const array = str.split('');这一步代码举例说明:

JavaScript如何实现计算器的四则运算功能

(图一)

  1. 在处理字符串的时候,可以看到 '3+6*5/6-3' 处理成了 ['3', '+', '6', '*', '5', '/', '6', '-', '3']。

  2. 然后在版本一代码中,可以看到我处理运算的执行顺序是 ['*', '/', '+', '-'],所以版本一只支持加减乘除一次运算;

  3. const index = array.findIndex(o => o === it); 这一步找到步骤 2 中的符号所在数组中的位置(说明一下,只用字符串的方法也可以实现,即找到字符串的位置,然后操作也可,只是数组更常用,也更容易理解)

  4. 观察处理后的数组,符号总是隔一位出现的,即便是优先级较高的 *、/ 法,也是符号所在的位置的前一项与后一项的运算结果。 array[index + 1] = mul(array[index - 1], array[index + 1]); 将符号所在的下一项的值为调用对应的操作函数的运算结果;

  5. 删除符号位与第一项:array.splice(index - 1, 2)

  6. 这时候可以看到最初定义的 array 数组一直在改变,以 node 环境下的打印结果为例(注意观察运算数组):

JavaScript如何实现计算器的四则运算功能

(图二)

可以看到每次打印都会打印初始数组以及通过 splice 方法处理之后的结果。

弊端:此版本不支持多次运算,即四则混合运算只能执行一次。同时,也不能够支持高位运算。

2. 版本二:实现高位数的运算

在图一中

JavaScript如何实现计算器的四则运算功能

如果是涉及高位(个位以上)的数值运算字符串的话,单纯的使用 split('') 方法会把两位数数值,处理成数组的两项,即影响运算结果。

所以我需要一个方法,在接收一个字符串以后,得到我想要的字符串:

JavaScript如何实现计算器的四则运算功能

(图三)

如图三所述, ary 即所需。

所以,图三中由 str 到 ary 的过程就是本次版本所需要实现的:

const split = () => {  const result = str.split('+')  // 遇到 + 处理为数组    .map(it => {      return it.split('-') // 遇到 - 处理为数组        .map(it => {          return it.split('*') // 遇到 * 处理为数组            .map(it => {              return it.split('/') // 遇到 / 处理为数组            })        })    })  return result.flat(3);}

我在设计这个算法的时候,一时间也没有太好的思路和想法,该函数处理字符串为一个多维数组,然后再将数组扁平化处理。如图四所示:

JavaScript如何实现计算器的四则运算功能

(图四)

图四中,执行该函数,得到一个多维数组(其实最高也只有三维数组),返回值 result 打印出来的结果可以看到,基本满足所需要的数组:['31', '+', '62', '*', '5', '/', '6', '-', '3'] 。

接下来,为其带上运算符:

  const add = (result, symbol) => {    let length = result.length;    while (length !== 1) {      result.splice(length - 1, 0, symbol); // 在每一项后面添加对应的运算符      length--;    }    return result; // 目的是得到一个改变长度的数组  }

比如传入 ['31', '62*5/6-3'] ,只需要在第一项之后补 '+' 即可。

实现的目的是考虑到多次运算的时候,为每一个因为 '+' 分割的数组中的项添加运算符,所以这里用到了 while 循环语句,并且由一个变量 length 控制(也可以遍历数组或者 for 循环数组实现这一步操作);

检验结果,如图五所示:

JavaScript如何实现计算器的四则运算功能

(图五)

这样就实现了这个任意长度数值数组输入时,返回带符号的数组。

【回顾一下】:

上面两个函数的整体实现就是,实现了根据符号分割数组,根据传入的数组与符号添加符号:

结合两个函数,并且简化一下代码(其实我个人还是喜欢写面条代码的,只是可能不利于阅读,但是看起来舒服一些~):

  // 定义添加字符函数  const add = (result, symbol) => {    let length = result.length;    while (length !== 1) {      result.splice(length - 1, 0, symbol); // 在每一项后面添加对应的运算符      length--;    }    return result; // 目的是得到一个改变长度的数组  }  const array = (strs = str) =>    add(strs.split('+'), '+').map(it =>      add(it.split('-'), '-').map(it =>        add(it.split('*'), '*').map(it =>          add(it.split('/'), '/')        )      )    ).flat(3);

即,任意运算字符串的传入都可以处理为所需数组如图六所示:

JavaScript如何实现计算器的四则运算功能

(图六)

array 函数在后面直接把内部处理函数的返回值绑定了。

对于上述算法的设计如果有更好的实现还希望有朋友可以指出,大家互相之间可以学习一下。

3. 支持多次的运算

回到版本一,目前的实现只支持一次的四则混合运算,更合理的实现应该是先运算乘除法,再运算加减法,而且先出现的先执行。

完整运算代码:

const calculator = (str) => {  const add = (result, symbol) => {    let length = result.length;    while (length > 1) {      result.splice(length - 1, 0, symbol);      length--;    }    return result;  }  const array = add(str.replace(/\s*/g, "").split('+'), '+').map(it => add(it.split('-'), '-').map(it => add(it.split('*'), '*').map(it => add(it.split('/'), '/')))).flat(3);;  // 先运算乘除法  while (array.includes('*') || array.includes('/')) {    const itSymbol = array.find(o => o === '*' || o === '/');    const index = array.findIndex(o => o === '*' || o === '/');    index > 0 && itSymbol === '*' ? array.splice(index - 1, 3, (Number(array[index - 1]) * Number(array[index + 1]))) : array.splice(index - 1, 3, (Number(array[index - 1]) / Number(array[index + 1])));  }  // 再执行加减法,即从左至右的计算  while (array.length > 1) {    array[1] === '+' ? array.splice(0, 3, (Number(array[0]) + Number(array[2]))) : array.splice(0, 3, (Number(array[0]) - Number(array[2])));  }  return Number(array[0]).toFixed(2);}

注:有必要说明一下,因为个人习惯不同,所以输入带有空格情况,所以这里在处理字符串之前首先用到了一个正则表达式 str.replace(/\s*/g, "") (去除空格)。
等等,我刚刚想到了什么?

JavaScript如何实现计算器的四则运算功能

如果大家都在输入的时候,自觉加一个空格隔开运算符与数值的话~

是不是我之前版本二中的字符串处理就可以省一下啦!!

所以作为开发者,一定要 注意规范,注意规范,注意规范!

上面完整代码中,

  1. 简化了调用加减乘除函数,改而用 array.splice(index - 1, 3, 运算) 运算直接可以操作两参数。

  2. 得到了可操作数组 array 后,先执行乘除法,再执行加减法。

  3. 乘除法里先判断 是否存在 * 或 / 两个符号,如果存在,则找到符号的位置,运算每一个乘除法,按数学的思维,谁在前先运算谁(但我依然规定了先运算所有的 *,再运算所有的 / 这种方式作为最终实现并放到了文章最开始。因为真正在运算的时候,乘除法的先后执行顺序得到的结果似乎并没有什么关系,而与我而言,我感觉在这套实现中,includes 与 find 的多次执行可能对性能上的损耗更大一些)

  4. 当所有的乘除法执行完毕后,就只剩下加减法了,这时候按顺序执行加减法即可。

  5. 最后保留两位小数。

其实这段代码更符合数学思维,先运算乘除法(谁在前先运算谁),再运算加减法。

如果大家有一些其他的想法,可以一起讨论一下~

三、思考

后端思维

1. 实现逆波兰表达式

1+2*3 这是一个中缀表达式,人脑很容易计算,结果为7。当然计算机也很容易处理这个表达式。

当我们输入1.2+(-1+3*1)*2,人脑需要思考一下,但计算机还是可以通过固定代码快速计算出结果。

但是,当我们随机输入中缀表达式 XXX 时,人脑可以手动计算出结果,计算机不可能一个表达式一个代码块,那么计算机怎么实现通用且快速的计算呢?答案就是后缀表达式。

中缀和后缀表达式在数据结构里有涉及到,我就不讲概念了,下面手动模拟一下计算机计算字符串表达式的过程。

2. 中缀表达式 => 后缀表达式

计算机易于计算的其实是后缀表达式,整个过程就是将已知的中缀表达式转换为后缀表达式。

1 定义【操作数栈】和【运算符栈】:

JavaScript如何实现计算器的四则运算功能

2 运算符栈出栈,操作数栈入栈,上式即可成为: 123*+ 这就是一个简单的后缀表达式

3 计算机在运算后缀表达式时:运算符栈读取 *,操作数栈读取 2,3 得到结果 6,;然后运算 1 + 6 = 7。

3. 较复杂的表达式计算

入栈:

( 后的- 作为负数进入操作数栈(如果作为符号位,后面计算会成1.1 - 30);

与上文一样,只是不同之处在于运算符栈,遇到 ( 以后先进入运算符栈;

JavaScript如何实现计算器的四则运算功能

直到遇到 )

JavaScript如何实现计算器的四则运算功能

1 使用 # 符号区分 负数、高位数、以及符号位

JavaScript如何实现计算器的四则运算功能

2 所以得到的后缀表达式为: #-1.1#3#10#*#+#2#/#

JavaScript如何实现计算器的四则运算功能

出栈过程:

  • 计算没有遇到符号位一 # 为准,依次取出

  • 直到遇到符号位之前,取出了三个数 -1.1 3 10

  • 遇到符号位以后,在结果栈中出栈,与符号计算结果 => 结果栈变为 -1.1 30

  • 依此计算:

JavaScript如何实现计算器的四则运算功能

  • 出栈完成后,就实现了对逆波兰表达式的求值运算。

前端思维

我拿到【实现一个支持四则混合运算的计算器】需求以后,首先想到的是字符串转数组,然后去操作数组,然后由于高级语言的特性,很多方法已经封装完成,所以实现起来相对容易一些。

当然,也可以采用前端的代码,用着后端的思维去实现也是一个选择。

以上是“JavaScript如何实现计算器的四则运算功能”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: JavaScript如何实现计算器的四则运算功能

本文链接: https://lsjlt.com/news/322086.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript如何实现计算器的四则运算功能
    小编给大家分享一下JavaScript如何实现计算器的四则运算功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、需求 + 最终实现注:只是前端实现1. 需求需...
    99+
    2023-06-29
  • JavaScript实现计算器的四则运算功能
    目录一、需求 + 最终实现1. 需求2. 说明:利用了字符串(split、replace)和数组(splice)的方法。3. 代码实现二、实现步骤1. 版本一:实现基础加减乘除2. ...
    99+
    2024-04-02
  • C#怎么实现计算器四则运算
    这篇文章主要讲解了“C#怎么实现计算器四则运算”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#怎么实现计算器四则运算”吧!初始化,实现四则运算using System;using...
    99+
    2023-06-29
  • Python实现简单的四则运算计算器
    一、算法 1、算法的主要思想就是将一个中缀表达式(Infix expression)转换成便于处理的后缀表达式(Postfix expression),然后借助于栈这个简单的数据结构,计算出表达式...
    99+
    2022-06-04
    计算器 简单 Python
  • javascript如何实现计算器功能
    这篇文章给大家分享的是有关javascript如何实现计算器功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、计算器功能介绍可以实现数据的加(+),减(-),乘(*),除(/),取余运算(%),以及实现数据的...
    99+
    2023-06-25
  • golang 四则运算计算器yacc归约手写实现
    目录缘起目标难点总体流程main.gotokens/tokens.gostates/states.golexer/lexer.goparser/tStackNode.goparser...
    99+
    2024-04-02
  • Go语言如何实现四则运算
    在Go语言中,四则运算是通过基本的算术运算符来实现的。常用的四则运算操作:1、加法(+): 用于将两个数相加;2、减法(-): 用于将第二个数从第一个数中减去;3、乘法(*): 用于将两个数相乘;4、除法(/): 用于将第一个数除以第二个数...
    99+
    2023-12-21
    go语言 四则运算
  • php实现四则运算的方法
    这篇文章给大家分享的是有关php实现四则运算的方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。php实现四则运算的方法:首先创建一个PHP示例文件;然后声明数字栈和符号栈;接着把运算串分解成每个字符到$arr数...
    99+
    2023-06-09
  • php四则运算怎么实现
    在PHP中,可以使用基本的数学运算符(+,-,*,/)来实现四则运算。以下是一个示例代码,演示了如何实现四则运算:```php```...
    99+
    2023-08-24
    php
  • JavaScript实现简单的计算器功能
    本文实例为大家分享了JavaScript实现简单计算器功能的具体代码,供大家参考,具体内容如下 具体要求如下: 实现代码: <html> <head>...
    99+
    2024-04-02
  • javascript实现简易的计算器功能
    本文实例为大家分享了javascript实现简易的计算器的具体代码,供大家参考,具体内容如下 javascript实现简易计算器,只有两个input输入框,简单实现加减乘除: <...
    99+
    2024-04-02
  • 如何理解SHELL四则运算
    本篇内容主要讲解“如何理解SHELL四则运算”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何理解SHELL四则运算”吧!1.操作符(let 标志符)+   &nb...
    99+
    2023-06-09
  • shell中怎么实现四则运算
    本篇文章为大家展示了shell中怎么实现四则运算,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1.简单方法代码如下:$ b=$((5*5+5-3/2)) $ echo $b29 在linux she...
    99+
    2023-06-09
  • JavaScript实现简单计算器小功能
    本文实例为大家分享了JavaScript实现简单计算器的具体代码,供大家参考,具体内容如下 此例为简单的计算器: 代码示例: <!DOCTYPE html> <h...
    99+
    2024-04-02
  • 怎么用javascript实现计算器功能
    这篇文章将为大家详细讲解有关怎么用javascript实现计算器功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 用javascript实现...
    99+
    2024-04-02
  • JavaScript如何实现计算两数的乘积功能
    这篇文章主要讲解了“JavaScript如何实现计算两数的乘积功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript如何实现计算两数的乘积功...
    99+
    2024-04-02
  • 功能强大:用Go语言实现四则运算,轻松应对复杂运算需求
    标题:功能强大:用Go语言实现四则运算,轻松应对复杂运算需求 随着计算机领域的发展,四则运算作为最基本的数学运算之一,常常在各类软件开发中被广泛使用。为了更好地满足复杂运算需求,许多开...
    99+
    2024-02-26
    go语言 四则运算 复杂需求
  • 实现一个【伪】四则运算封闭的符号运算和
    最后的效果: if __name__ == '__main__': import doctest doctest.testmod() x = Symbols("x") print(x * 2 + 1 == ...
    99+
    2023-01-31
    符号
  • js中如何实现计算器功能
    这篇文章将为大家详细讲解有关js中如何实现计算器功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。代码如下:<!DOCTYPE html> ...
    99+
    2024-04-02
  • Python 正则表达式实现计算器功能
    需求: 用户输入运算表达式,终端显示计算结果 代码: # !/usr/bin/env/ python3 # -*- coding: utf-8 -*- """用户输入计算表达式,显示计算结果""" ...
    99+
    2022-06-04
    计算器 功能 正则表达式
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作