js实现计算器 提供算术表达式求值

来源:互联网 发布:linux脚本编程 编辑:程序博客网 时间:2024/06/05 21:02

//html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>计算器</title>
<style type="text/css" >
  @import "calculator.css";
</style>


</head>

<body>

<div>
 <div id="in">
   <input name="in" type="text"   class="clsin"  id="input"  value="" readonly="readonly" />
   <input   type="button" name="=" value="=" onClick="exp_result()"/>
 </div>

 <div id="num">
  <input  type="button" name="seven" value="7"  onClick="test(this);"/>
  <input  type="button" name="8" value="8" onClick="test(this);"/>
  <input  type="button" name="9" value="9" onClick="test(this)"/>
  <input  type="button" name="/" value="/" onClick="test(this)"/>
  <!--span id="showValue"></span-->
  <br />
  <input  type="button" name="4" value="4" onClick="test(this)"/>
  <input  type="button" name="5" value="5" onClick="test(this)" />
  <input  type="button" name="6" value="6" onClick="test(this)"/>
   <input  type="button" name="*" value="*" onClick="test(this)"/>
  <br />

  <input  type="button" name="1" value="1" onClick="test(this);"/>
  <input  type="button" name="2" value="2" onClick="test(this);"/>
  <input  type="button" name="3" value="3" onClick="test(this);"/>
   <input  type="button" name="-" value="-" onClick="test(this);"/>
  <br />

  <input  type="button" name="0" value="0"      onClick="test(this);"/>
  <input  type="button" name="+/-" value="("    onClick="test(this);"/>
  <input  type="button" name="." value=")"      onClick="test(this);"/>
   <input  type="button" name="+" value="+"     onClick="test(this);"/>
 
 </div>
 
</div>

</body>
<script type="text/javascript" src="calculator.js"></script>
</html>


//CSS

/* CSS Document */
body
{    
  /*   padding-right:40%;
     padding-left:40%;*/
     text-align:center;
     
}

div{
    background-color:orange;
    height:300px;
    width:300px;
    margin-left:auto;
    margin-right:auto;
    margin-bottom:auto;
    margin-top:50px;
    border-style: groove;
    border-color: Green;
   
    
/*    margin-top:auto;*/
}
#in{   
       position:relative;
       margin-left:20px;
       margin-top:10px;
       height:27px;
       width:260px;
       background:red;
       top:40px
    
    }
.clsin
    {
        height:27px;
        width:200px;
        background-color:#FFF;
        
        
    }
#num{
        position:relative;
        margin-left:20px;
        margin-top:45px;
        height:150px;
        width:250px;
        background-color:green;
        text-align:left;
    }
#num input
   {
       margin-right:10px;
       margin-top:10px;
       width:35px;
   }


//js


str_exp="";  //存放表达式
function test(obj)      //数字 运算符 btn   click
{
 
       str_exp+=obj.value;
       document.getElementById("input").value=str_exp;
   
}
                 
function compare( ch1, ch2)                  //比较运算符ch1和ch2优先级
{
   array1=new Array('+','-','*','/','(',')','@');
   array20=new Array('>','>','<','<','<','>', '>');
   array21=new Array( '>','>','<','<','<','>','>');
   array22=new Array( '>','>','>','>','<','>','>');
   array23=new Array('>','>','>','>','<','>','>');
   array24=new Array('<','<','<','<','<','=',' ');
   array25=new Array('>','>','>','>',' ','>','>');
   array26=new Array( '<','<','<','<','<',' ','=');
   array2=new Array(array20,array21,array22,array23,array24,array25,array26);
   
//   b[7][7]={'>','>','<','<','<','>','>',    //  +
//               '>','>','<','<','<','>','>',      //  -
//               '>','>','>','>','<','>','>',      //  *
//                '>','>','>','>','<','>','>',     //  /
//                '<','<','<','<','<','=',' ',     //  (
//                 '>','>','>','>',' ','>','>',    //  )
//                 '<','<','<','<','<',' ','=' };  //  @
                 
   for(var i=0;ch1!=array1[i];i++);             
   for(var j=0;ch2!=array1[j];j++);
       
   return array2[i][j];
}

function operate(a,preop,b)   //计算a?b的值
{
 //  var num1=parseInt(a,10);
 //  var num2=parseInt(b,10);
   
   
   var num1=parseFloat(a);
   var num2=parseFloat(b);
   
//   alert("a:"+num1+preop+"b:"+num2);
   switch(preop)
   {
   case'+':return(num1+num2);break;
   case'-':return(num1-num2);break;
   case'*':return(num1*num2);break;
   case'/':return(num1/num2);break;
//   default: cout<<"erro"<<endl;return 0;   
   }
}
function isNum( ch)                               //判断读取ch是否为操作数
{
   if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='@')
       return 0;
   else
       return 1;
}  
    
function extend(str)       //将开始一定情况下‘-’转换为'(0-1)*’,从而支持负数  
{
    
     var str1=new Array();
     if(str.charAt(0)=='-')
     {
         str1+="(0-1)*";
     }
     else
     {
       str1+=str.charAt(0);
     }
     for(var i=1;i<str.length;i++)
     {
         if(str.charAt(i)=='-'&&str.charAt(i-1)=='(')
         {
           str1+="(0-1)*";
         }
         else
          str1+=str.charAt(i);
     
     }
     return str1;

}

function divided(str)    //分离表达式中操作数与操作符存放到返回值中
{
 
  var str2=extend(str);
//  alert(str2);
  var str_temp=new Array();
  var j=0;
  var expTemp;
  var expPre;
  for(var i=0;i<str2.length;i++)
  {
   //  alert(str2.charAt(i));
     expTemp="";
     expTemp=str2.charAt(i);
     
     if(i==0)
     str_temp[0]=expTemp;
 
     if(i>0)
     {
      expPre=str2.charAt(i-1); ///////////////////////!!
 
      if(isNum(expTemp)&&isNum(expPre))   //判断前后连续取到的是否都是数字字符,是则拼接
      {
        str_temp[j-1]+=expTemp;        
        j--;
      }    
       else
       {                             
         str_temp[j]=expTemp;
       }
     
     }
     
     j++;
     
  }
  return str_temp;
      
}

function exp_result()
{
    str_exp=str_exp+'@';
    str=divided(str_exp);
    numArray=new Array();   //存放操作数
    symbolArray =new Array();//存放操作符
    symbolArray.push('@');
 //   numArray.push('@');
   
//  alert(str.length);
    for(var i=0;str[i]!='@'||symbolArray[symbolArray.length-1]!='@';i++)
    {
//       alert(str[i]);
//       alert(symbolArray[symbolArray.length-1]);
       if(isNum(str[i]))
        {
 //         alert("Num push:"+str[i]);
          numArray.push(str[i]);  
        }
       else
       {
 //       alert("symbol:"+str[i]);
        preop=symbolArray[symbolArray.length-1];   //取栈顶元素
        switch(compare(preop,str[i]))
        {
           case'<':symbolArray.push(str[i]);break;
           case'=':symbolArray.pop();break;
           case'>':b=numArray.pop();a=numArray.pop();preop=symbolArray.pop();  //取两操作数与之前操作符运算
                   numArray.push(operate(a,preop,b)); //计算结果入栈
                 // str.push(str[i]);  //当前操作符入栈
                   i--;     //继续与之前的操作符比较
                   break;  
        }
       }
    }
    if(isNaN(numArray[0]))
    {
      alert("算术表达式输入有误!!");
    }
    else
    alert("结果为:"+numArray[0]);
    
    str_exp="";
    document.getElementById("input").value=str_exp;
    
}