中缀转后缀表达式的算法概要描述
/**
* 中缀表达式转换成 后缀表达式
*
* 栈A,后缀串B
* 源S,从左往右读入S
* 1. 操作数直接添加到B
* 2. ( 直接入栈
* 3. ) 从栈A中依次弹出操作符添加到B,直到弹出(
* 4. 操作符,如果栈顶元素的优先级比当前高,则弹出栈顶元素添加到B,直到栈顶元素小于当前操作符,操作符入栈A
* 5. 函数递归处理
* 6. S读完后,如果栈非空,弹出所有元素依次追加到B
*
* 中缀 1+2*(6/2+3*2+7*(2*2))+2
* =>
* 后缀 1262/32*+722**+*+2+
*/
测试代码
var nodelist=string_to_nodelist('1+2*(6/2+3*2+7*(2*2))+2');
var post_stock=postfix(nodelist);
alert(post_stock.print());
/** 节点定义 **/
function node(i_type/*1 操作数 2. 操作符 3 函数*/,s_value/*字符*/,i_level/* 1 + - 2 * / 3 函数 4 () */)
{
return {type:i_type,value:s_value,level:i_level,print:function(){return s_value;}};
}//fun
/** 栈定义 **/
function stock()
{
var stock=new Array();
/*入栈*/
function stock_push(s_value)
{
stock[stock.length]=s_value;
}//fun
/*出栈*/
function stock_pop()
{
if( stock.length < 1 )
return null;
var value=stock[stock.length-1];
stock.splice(stock.length-1,1);//删除元素
return value;
}//fun
/*顶部元素*/
function stock_top()
{
if( stock.length < 1 )
return null;
return stock[stock.length-1];
}//fun
/*大小*/
function stock_size()
{
return stock.length;
}//fun
//for debug
function stock_print()
{
var s='';
for(var i=stock.length-1;i>=0;i--)
if( typeof stock[i].print != undefined )
s += stock[i].print();
else
s +=stock[i];
return s;
}//fun
return {push:stock_push,pop:stock_pop,top:stock_top,size:stock_size,print:stock_print};
}//fun
function string_to_nodelist(expression)
{
var index=0;
var node_list=new Array();
var head_2='', head_3='';
//先解析出每个单位
while( index < expression.length )
{
head_2=expression.substr(index,2);
head_3=expression.substr(index,3);
if( ('log'==head_3) || ('cos'==head_3) || ('sin'==head_3)|| ('tan'==head_3) )
{
node_list[node_list.length]=new node(3,head_3,3);
index+=3;
}//if
else if( ('ln'==head_2))
{
node_list[node_list.length]=new node(3,head_2,3);
index+=2;
}//if
else if( '+' == expression[index] || '-' == expression[index] )
{
node_list[node_list.length]=new node(2,expression[index],1);
index+=1;
}
else if( '*' == expression[index] || '/' == expression[index] )
{
node_list[node_list.length]=new node(2,expression[index],2);
index+=1;
}
else if( '(' == expression[index] || ')' == expression[index] )
{
node_list[node_list.length]=new node(2,expression[index],4);
index+=1;
}
else
{
var len=1;
while( (index+len <expression.length )&&(expression[index+len] <= '9') && (expression[index+len] >= '0') )
{
len++;
}//while
node_list[node_list.length]=new node(1,expression.substr(index,len),0);
index += len;
}//
}//while
return node_list;
}//fun
function postfix(node_list)
{
var stock_out=new stock();//后缀表达式,用栈表示 从底到上 对应 从左到右
var stock_return =new stock();//返回的后缀表达式,从上到下,对应表达式的左到右
var stock_opr=new stock();//保存转换过程中的运算符栈
var index=0;
while( index < node_list.length )
{
switch(node_list[index].type)
{
case 1://#1. 操作数直接添加到S
{//操作数
stock_out.push(node_list[index]);
index++;
break;
}//case
case 2:
{
if( '(' == node_list[index].value )//2. ( 直接入栈
stock_opr.push(node_list[index]);
else if( ')' == node_list[index].value)//3. ) 从栈A中依次弹出操作符添加到S,直到弹出(
{
while( (null != stock_opr.top()) && ('(' != (stock_opr.top()).value) )
stock_out.push(stock_opr.pop());
if( (null == stock_opr.top() ) || '(' != (stock_opr.top()).value )
return null;//error
stock_opr.pop();//弹出(
}//else if
else //4. 操作符,如果栈顶元素的优先级比当前高,则弹出栈顶元素添加到S,直到栈顶元素小于或等于当前操作符,操作符入栈A
{
while( (null != stock_opr.top()) && (('(' != stock_opr.top().value))&&((stock_opr.top()).level >= node_list[index].level) )
stock_out.push(stock_opr.pop());
stock_opr.push(node_list[index]);
}//else
index++;
break;
}//case
case 3:
{//5. 函数递归处理
var sub_nodelist=new Array();//存放函数后面的参数
var left_num=0;
var fun=node_list[index].value;//函数
index++;
while( (null !=node_list[index]) && ((2 != node_list[index].type) || ('(' ==node_list[index].value )||((left_num>0) )) )
{
if( '('== node_list[index].value )
left_num++;
if( ')' == node_list[index].value )
left_num--;
sub_nodelist[sub_nodelist.length]=node_list[index];
index++;
}//while
//这里的calculate 是对后缀表达式的求值实现
var sub_value= calculate(postfix(sub_nodelist));
if( isNaN(sub_value) )
return null;
switch( fun)
{
/**
* 这里依次处理你需要在四则运算中支持的函数
* 如
* case 'log':
* {
* sub_value=Math.log(sub_value);
* stock_out.push(new node(1,sub_value,0));//将结果放入
* break;
* }//case
**/
default:
return null;
}//swtich
}//case
default:
break;
}//switch
}//while
//6. S读完后,如果栈非空,弹出所有元素依次追加到S
while( null != stock_opr.top() )
stock_out.push(stock_opr.pop());
while( null != stock_out.top())
stock_return.push(stock_out.pop());
return stock_return;
}//fun
