中缀表达式转后缀表达式 javascript版

 

下一篇是后缀表达式的求值

 

完整的中缀转后缀,并求值的代码文件在这里
中缀转后缀表达式的算法概要描述
/**
* 中缀表达式转换成 后缀表达式
*
*	栈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
 
posted @ 2012-04-27 11:56  toxot  阅读(650)  评论(0编辑  收藏  举报