使用栈实现高级计算器

    一般我们在做计算器程序的时候,只能让用户输入两个数值计算,但是如果用户的表达式非常复杂呢?如:50-20*80/2-10-5*11,用户需要根据运算符的优先级来依次输入数值进行计算。那么,有没有一个简单点的方法,用户直接输入整个表达式,程序自动判断运算符优先级进行计算,最后得出结果呢?后来在网上查找了一下,发现要实现这个功能,必须要使用栈来实现,于是重新学习了数据结构的知识,根据栈的原理使用javascript完成了这个功能。补充一下,在javascript中,其实提供了一个eval()函数可以实现这个功能,eval()函数本身要强大得多,它可以把一个字符串当作一段程序来执行;这里只模拟它实现计算的底层原理代码。eval()更详细的功能可以参考API文档。

<!DOCTYPE>

<html>

 <head>

  <title> 使用栈实现 </title>


  <meta charset="utf-8"/>


  <script type="text/javascript">


function MyStack(){

this.stackTop = -1;// 栈的指针

this.stackSize = 50;// 栈的容量

this.stack = new Array();


// 入栈操作

this.push = function(val){

if(this.stackTop == this.stackSize-1){

alert("栈已经满了");

}

this.stackTop++;

this.stack[this.stackTop] = val;

}


// 出栈操作

this.pop = function(){

if(this.stackTop == -1){

alert("栈内没有数据");

}

var stackTopVal = this.stack[this.stackTop];

this.stackTop--;

return stackTopVal;

}


// 显示栈内的数据

this.show = function(){

if(this.stackTop == -1){

alert("栈内没有数据");

}

for(var i = this.stackTop; i>-1; i--){

alert(this.stack[i]);

}

}


// 判断当前字符是数值还是运算符

this.isOper = function(cha){

if(cha == "+" || cha == "-" || cha == "*" || cha == "/"){

return true;

}else{

return false;

}

}


// 判断栈是否为空

this.isEmpty = function(){

if(this.stackTop == -1){

return true;

}else{

return false;

}

}


// 获取运算符的优先级

this.PRI = function(cha){

if(cha == "*" || cha == "/"){

return 1;

}else if(cha == "+" || cha == "-"){

return 0;

}

}


// 获取栈顶的字符

this.getTop = function(){

return this.stack[this.stackTop];

}


// 计算函数

this.result = function(num1,num2,oper){

var res = 0;

switch(oper){

case '+':

res = Number(num2) + Number(num1);// 数据必须先要转换

break;

case '-':

res = Number(num2) - Number(num1);

break;

case '*':

res = Number(num2) * Number(num1);

break;

case '/':

res = Number(num2) / Number(num1);

break;

}

return res;

}

}


// 定义两个栈:数值栈和运算符栈

var valueStack = new MyStack();

var operStack = new MyStack();


function Count(){

var exp = document.getElementById("exp").value;


var index = 0;// 扫描指针

//var cha = exp.substr(index, 1);

//alert(cha);

while(true){

// 取出字符

var cha = exp.substr(index, 1);

// 判断cha

if(operStack.isOper(cha)){

// 是运算符,判断运算符栈是否为空

if(operStack.isEmpty()){

// 放入运算符栈

operStack.push(cha);

}else{

// 判断运算符的优先级

var chaPRI = operStack.PRI(cha);

var stackPRI = operStack.PRI(operStack.getTop());


if(chaPRI <= stackPRI){

// 从数值栈出栈两个数值

var num1 = valueStack.pop();

var num2 = valueStack.pop();


// 再从运算符栈出栈一个运算符

var oper = operStack.pop();


// 调用计算函数

var res = operStack.result(num1, num2, oper);


// 把结果放入数值栈

valueStack.push(res);


// 把当前运算符放入运算符栈

operStack.push(cha);

}else{

operStack.push(cha);

}

}


}else{

// 是数值,放入数值栈

valueStack.push(cha);

}


// 让扫描指针指向下一个字符

index++;

// 判断是否扫描完毕,扫描完毕,break.

if(index == exp.length){

break;

}


}


// 如果运算符栈不空就一直计算

while(!operStack.isEmpty()){

// 从数值栈出栈两个数值

var num1 = valueStack.pop();

var num2 = valueStack.pop();

// 再从运算符栈出栈一个运算符

var oper = operStack.pop();

// 调用计算函数

var res = operStack.result(num1, num2, oper);

// 把结果放入数值栈

valueStack.push(res);

}


// 在退出循环后,数值栈中留下的数值,就是最终结果

alert(exp+'结果='+valueStack.getTop());

}


  </script>

 </head>


 <body>

 <input type="text" id="exp" value="1+2*3+2"/>

 <input type="button" value="计算" onClick="Count();"/>

 </body>

</html>


转载于:https://my.oschina.net/hehongbo/blog/269750

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值