JS实现多功能计算器

(编辑:jimmy 日期: 2024/12/24 浏览:2)

本文实例为大家分享了JS实现多功能计算器的具体代码,供大家参考,具体内容如下

1、开发语言 HTML+CSS+JavaScript

2、开发工具 Visual Studio Code

3、项目GitHub地址:计算器 (喜欢可以给一个star)

4、项目运行截图:

JS实现多功能计算器

5、技术分析:由于除了简单的四则运算,还需要进行括号匹配,以及优先级的运算。采用后缀表达式的形式进行处理,同时通过模拟栈的特点运用JS自带的数组进行处理。由于代码有详细的注释,所以直接上代码。

6、项目代码:

compute.html:

<!--
 * @Author: CSU_XZY
 * @Date: 2020-10-15 21:17:33
 * @LastEditors: CSU_XZY
 * @LastEditTime: 2020-10-16 22:07:08
 * @FilePath: \第二天\计算器\compute.html
 * @Description: just to play
-->
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>计算器</title>
</head>
<style>
 *{
  margin: 0;
  padding: 0;
 }
 body{
  background-color: #FCFDFE;
 }
 .container{
  overflow: hidden;
  box-shadow: 0 0 3px 0 rgba(0, 0, 0, .3);
  margin: 150px auto;
  width: 548px;
  height: 274px;
  background-color: #fff;
 }
 .box{
  background-color: #fcfdff;
  margin: 15px auto;
  overflow: hidden;
  width: 514px;
  height: 244px;
 }
 .number{
  width: 514px;
  height: 189px;
 }
 .text{
  width: 514px;
  height: 55px;
  margin: 0;
 }
 span{
  border-top: solid 1px #ebebeb;
  border-right: solid 1px #ebebeb;
  box-sizing: border-box;
  float: left;
  display: block;
  width: 25%;
  font-size: 16px;
  color: #333;
  background-color: #fff;
  line-height: 37px;
  cursor: pointer;
  text-align: center;
  font-weight: 10px;
 }
 span:hover{
  background-color: #d3d7d4;
 }
 span:active{
  background-color: #afdfe4;
  
 }
 
 .text>p{
  text-align: right;
  width: 514px;
  height: 24px;
  line-height: 25px;
  font-size: 25px;
 }
 .number>div{
  width: 514px;
  height: 37.8px;
 }
 .around{
  background-color: #f9f9f9;
  color: #f60;
 }
 .compute{
  color: #333;
 }
 .bottom{
  background-color: #fff;
  color: #f60;
 }
 .dot{
  font-size: 23px; 
  font-weight: 19px;
 }
</style>
<body>
 <div class="container">
  <div class="box">
   <div class="text">
    <p id="text"></p>
    <p id="display"></p>
   </div>
   <div class="number">
    <div class="around">
     <span onclick="showDetails(this)" data-value="(" class="around">(</span>
     <span onclick="showDetails(this)" data-value=")" class="around">)</span>
     <span onclick="showDetails(this)" data-value="D" title="回退一位数" class="around">del</span>
     <span onclick="showDetails(this)" data-value="C" class="around compute">C</span>
    </div>
    <div>
     <span onclick="showDetails(this)" data-value="7">7</span>
     <span onclick="showDetails(this)" data-value="8">8</span>
     <span onclick="showDetails(this)" data-value="9">9</span>
     <span onclick="showDetails(this)" data-value="÷" class="around">÷</span>
    </div>
    <div>
     <span onclick="showDetails(this)" data-value="4">4</span>
     <span onclick="showDetails(this)" data-value="5">5</span>
     <span onclick="showDetails(this)" data-value="6">6</span>
     <span onclick="showDetails(this)" data-value="x" class="around">x</span>
    </div>
    <div>
     <span onclick="showDetails(this)" data-value="1">1</span>
     <span onclick="showDetails(this)" data-value="2">2</span>
     <span onclick="showDetails(this)" data-value="3">3</span>
     <span onclick="showDetails(this)" data-value="-" class="around">-</span>
    </div>
    <div>
     <span onclick="showDetails(this)" data-value="0">0</span>
     <span onclick="showDetails(this)" data-value="." class="around bottom dot">.</span>
     <span onclick="showDetails(this)" data-value="=" class="around bottom">=</span>
     <span onclick="showDetails(this)" data-value="+" class="around">+</span>
    </div>
   </div>
  </div>
 </div>
</body>
<script type="text/javascript" src="/UploadFiles/2021-04-02/compute.js">

compute.js:

/*
 * @Author: CSU_XZY
 * @Date: 2020-10-15 21:17:45
 * @LastEditors: CSU_XZY
 * @LastEditTime: 2020-10-17 00:04:41
 * @FilePath: \第二天\计算器\compute.js
 * @Description: just to play
 */
var ysf = ['+','÷','=',')','%','x','-','D'];
var sizeyunsuan = ['+','÷','(','x','-'];
var isNumber = ['1','2','3','4','5','6','7','8','9','0','.'];


function showDetails(number)
{
 var number = number.getAttribute("data-value");
 var text = document.getElementById('display').innerText;
//回退一个文字
 if(number === 'D')
 {
  text = text.substring(0,text.length-1);
  document.getElementById('display').innerHTML=text;
  return;
 }
//判断第一个数字是不是运算符
 else if(judgeBegin(number) && text == "")
 return;
//判断是否是连续两个运算符一起输入
 else if(judgeBegin(number) && judgeNext(text,number) && text[text.length-1] !== ')')
 return;
//判断第一个输入是不是‘.',如果是变为0.
 else if(number === '.' && text == "")
 number = "0.";
//如果输入归0,清空输入
 else if(number === 'C')
 {
  document.getElementById('text').innerHTML="";
  document.getElementById('display').innerHTML="";
  return;
 }
//输入是等号就判断
 else if(number === '=')
 {
  //将数字与运算符分开
  let array = [];
  let n = text.length;
  for(let i = 0; i < n; i++)
  {
   var JudgeNumber = true;
   let res = "";
   //判断第一个数字是否是负号
   if(i===0 && text[i] === '-')
   {
    res+=text[i];
    i++;
   }
   //判断是不是在运算符之后的减号,是就变为负号
   if(i !== 0 && near(array[array.length-1]) && text[i] === '-')
   {
    res+=text[i];
    i++;
   }
   //判断是否为连续的数字
   while(JudgeIsNumber(text[i]) && i < n)
   {
    res += text[i];
    i++;
    JudgeNumber = false;
   }
   //如果不为数字了要回退一个
   if(JudgeNumber === false)
   i--;
   //判断其他运算符
   if(JudgeNumber === true)
   if(judgeBegin(text[i]) || text[i] === '(' || text[i] === '-' || text[i] === ')')
   res+=text[i];
   array.push(res);
  }
  //
   console.log(array);
  //中缀表达式变为后缀表达式
  var hz = houZhui(array);
  console.log(hz);
  var result = compute(hz);
  document.getElementById('text').innerHTML = text;
  document.getElementById('display').innerHTML = result;
  return;
 }
 text+=number;
 document.getElementById('display').innerHTML=text;
}

//判断是不是运算符
function judgeBegin(number)
{
 for(let i = 0; i < ysf.length; i++)
 {
  if(ysf[i] === '-')
  continue;
  if(ysf[i] === number)
  return true;
 }
 return false;
}

//判断是否输入两个连续的运算符
function judgeNext(text,number)
{
 if(number === '-')
 return;
 let a = text.length;
 if(judgeBegin(text[a-1]) && judgeBegin(number))
 return true;
 return false;
}

//判断输入的字符里面是不是数字
function JudgeIsNumber(number){
 for(let i = 0; i < isNumber.length; i++)
 {
  if(isNumber[i] === number)
  return true;
 }
 return false;
}

//判断减号前面是否有别的运算符从而确定是不是负号
function near(number)
{
 for(let i = 0; i < sizeyunsuan.length; i++)
 {
  if(sizeyunsuan[i] === number)
  return true;
 }
 return false;
}

//中缀表达式改为后缀表达式
function houZhui(array)
{
 var stack = [];
 var textArea = [];
 for(let i = 0; i < array.length; i++)
 {
  if(near(array[i]) || array[i] === ')')
  {
   //如果是空直接入栈
   if(stack.length === 0)
   stack.push(array[i]);
   //如果栈顶为左括号直接入栈
   else if(stack[stack.length-1] === '(' && array[i] !== ')')
   stack.push(array[i]);
   //如果输入左括号直接入栈
   else if(array[i] === '(')
   stack.push(array[i]);
   //如果输入的是右括号
   else if(array[i] === ')')
   {
    //一直弹出直到遇到左括号
    while(stack[stack.length-1] !== '(')
    {
     let a = stack.pop();
     textArea.push(a);
    }
    //弹出左括号
    stack.pop();
   }
   else if(array[i] === '-' || array[i] === '+')
   {
    while(stack[stack.length-1] !== '(' && stack.length !== 0)
    {
     let a = stack.pop();
     textArea.push(a);
    }
    stack.push(array[i]);
   }
   else if(array[i] === 'x' || array[i] === '÷')
   {
    while(stack[stack.length-1] !== '(' && stack[stack.length-1] !== '+' && stack[stack.length-1] !== '-' && stack.length !== 0)
    {
     let a = stack.pop();
     textArea.push(a);
    }
    stack.push(array[i]);
   }
  }
  else{
   textArea.push(array[i])
  }
 }
 while(stack.length !== 0)
 {
  let a = stack.pop();
  textArea.push(a);
 }
 return textArea;
}

//计算后缀表达式
function compute(array){
 var NUMBER = [];
 for(let i = 0; i < array.length; i++)
 {
  //是运算符就计算
  if(near(array[i])){
   //加法
   if(array[i] === '+')
   {
    if(NUMBER.length < 2)
    return "错误";
    else
    {
     let a = NUMBER.pop();
     let b = NUMBER.pop();
     let c = a + b;
     NUMBER.push(c);
    }
   }
   //减法
   else if(array[i] === '-')
   {
    if(NUMBER.length < 2)
    return "错误";
    else
    {
     let a = NUMBER.pop();
     let b = NUMBER.pop();
     let c = b - a;
     NUMBER.push(c);
    }
   }
   //乘法
   else if(array[i] === 'x')
   {
    if(NUMBER.length < 2)
    return "错误";
    else
    {
     let a = NUMBER.pop();
     let b = NUMBER.pop();
     let c = a * b;
     NUMBER.push(c);
    }
   }
   //除法
   else if(array[i] === '÷')
   {
    if(NUMBER.length < 2)
    return "错误";
    else
    {
     let a = NUMBER.pop();
     let b = NUMBER.pop();
     if(a === 0)
     return "0不能作为除数";
     let c = b / a;
     NUMBER.push(c);
    }
   }
  }
  else{
   if(array[i][0] === '-')
   {
    let temp = array[i].substring(1,array[0].length);
    let num = parseFloat(temp);
    num = -num;
    NUMBER.push(num);
   }
   else{
    let num = parseFloat(array[i]);
    NUMBER.push(num);
   }
   console.log(NUMBER);
  }
 }
 if(NUMBER.length !== 1)
 return "错误";
 else
 {
  let b = String(NUMBER[0]);
  return b;
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

一句话新闻

一文看懂荣耀MagicBook Pro 16
荣耀猎人回归!七大亮点看懂不只是轻薄本,更是游戏本的MagicBook Pro 16.
人们对于笔记本电脑有一个固有印象:要么轻薄但性能一般,要么性能强劲但笨重臃肿。然而,今年荣耀新推出的MagicBook Pro 16刷新了人们的认知——发布会上,荣耀宣布猎人游戏本正式回归,称其继承了荣耀 HUNTER 基因,并自信地为其打出“轻薄本,更是游戏本”的口号。
众所周知,寻求轻薄本的用户普遍更看重便携性、外观造型、静谧性和打字办公等用机体验,而寻求游戏本的用户则普遍更看重硬件配置、性能释放等硬核指标。把两个看似难以相干的产品融合到一起,我们不禁对它产生了强烈的好奇:作为代表荣耀猎人游戏本的跨界新物种,它究竟做了哪些平衡以兼顾不同人群的各类需求呢?