中缀转后缀 c++实现(数据结构)

一、功能实现:

输入正常的中缀表达式,通过程序实现转化成后缀表达式,并且输出结果。

二、思路分析:
1. 输入:三个示例

2+4x6-8/2+5
2+(3x4)-5+1
3+(11)*2-6

2. 分析:

2.1 从左边开始读取,读到数字直接输出不入栈,读到运算符入栈,入栈之前判断前面的运算符是否比它的优先级高,如果比它高就入栈,如果比它低或者相等的优先级,就先让栈顶的运算符出栈,然后再入栈。
2.2 带括号的情况:当读取到 ( 符时,不管前面是什么运算符,直接入栈,然后没遇到 ) 符之前都是按上面正常运算,直到 ) 符时,)不用入栈然后直接出栈两个,第一个是运算符,第二个是 ( 符,然后直到栈为空。
2.3 整数10以上:定义一个LEN记录int OPER= 0;标识, 读取到 ( 符号时打开标识OPER =1 ,LEN开始记录len++;,读到 ) 符号时,OPER关闭OPER =0;之后得到LEN长度,比如:(11) -> 2,就是前面2个是一坨数据,然后就很长的一段计算,代码中有这里就不扯。

三、思路图:

在这里插入图片描述
在这里插入图片描述

四、代码实现:
#include <iostream>
#include <sstream>
using namespace std;

static int IDX = 0;			//压栈用 
static int NUM_LEN = 0;		//查括号中的数字大小 
static stringstream ss; 

static string RESULT = ""; 	//结果缓存 
/**
	功能实现 :	中缀表达式转后缀表达式
	@auther	 :
	@date	 : 
*/
class Stack{
	private:
		char data;			//存数字或者字符
	public:
		void setData(char data){
			this->data = data;
		} 
		char getData(){
			return this->data;
		}
		Stack * next;		//指向下一个类 
};

//遍历栈
void getStacks(Stack * top){
	Stack * node;
	node = top->next;
	while(node != NULL){
		RESULT += node->getData(); 
		node = node->next;
	}
} 

//展示栈
void show(Stack * top){
	Stack * node;
	int i = 0;
	node = top->next;
	while(node != NULL){
		cout<<node->getData();
		node = node->next;
		i++;
	}
	cout<<"\nthis stack length is :"<<i<<endl;
} 

//删除指定符号 
string delString(string str,int start,int end){
	//然后通过erase进行删除:
	str = str.erase(start,(end-start));           //从pos这个位置开始,删除1个字符
	return str; 
} 

//最后结果展示
void resultView(){
	string value = RESULT;
	//判断结果是否存在[]号
	int start =  RESULT.find('[');		//始 
	int end = RESULT.find(']');			//终
	if(start == -1){
		cout<<"result is :"<< value<<endl;
	}else{
		int cc = 0; 
		string len = RESULT.substr(start+1,(end-start-1));	
		ss << len;				//len = 4 ,cc = 44; 
		ss>>cc;
		cc = cc % 10;			// 
		//插入括号
		value.insert(start-cc,"(");
		value.insert(end-1,")");
		//删除[
		start = value.find('[');
		end = value.find(']');
		value = delString(value,start,end+1);

		cout<<"This result is: "<<value<<endl;
	}
} 

//查找改元素在栈内第几个 
int select(Stack * top,char val){
	Stack * node;
	int i = 0;
	node = top->next;
	char resu;
	while(node != NULL){
		if(node->getData() == val){
			return i;
		}else{
			node = node->next;
			i++;
		}
	}
	return -1;
} 

//删除元素
char pop(Stack * top){
	Stack * node;
	node = top->next;
	char val;
	if(top->next == NULL){
		return 0;
	}else{
		val = node->getData();
		top->next = node->next;
		delete(node);
		return val;
	}
} 

//存入到栈里面
void push(Stack * top,char cc){
	Stack * p = new Stack;
	//判断  如果高级运算符再栈中就先放出再入栈 
	if(top->next == NULL){
		p->setData(cc);
		p->next = top->next;
		top->next = p;
	}else{ 
		char one = (top->next)->getData();	
		
		if(cc == '('){			//遇到括号就压栈 
			 IDX++; 
			 p->setData(cc);
			 p->next = top->next;
			 top->next = p;
			 NUM_LEN = 0;		//开始计下标 
		} else if(cc == ')'){
			//判断是否包含运算符
			//存在运算符
			int pero = select(top,'(');
			if(pero > 0){	//存在运算符,不是纯数字 
				//出头栈并且不入栈再删除多一个栈
				RESULT += pop(top); 
				pop(top); 		//出(号栈 ,不输出 
				IDX--; 
			}else{//不存在运算符,大于等于10的数
				ss << NUM_LEN;
				string s =  "["+ ss.str() +"]"; 
				RESULT += s; 
				pop(top); 		//出(号栈 ,不输出 
				IDX--; 
			} 		 
			
		}
		
		if(IDX == 0){
			//one 为栈顶元素,如果进栈元素大于等于栈顶元素,就进栈,如果小于就输出栈顶元素	
			if(cc == '+' || cc == '-' ){
				//cc 优先级小于等于栈头 
				//将头出栈,再新的运算符入栈
				 RESULT += pop(top); 
				 p->setData(cc);
				 p->next = top->next;
				 top->next = p;
				
			}else if(cc == '*' || cc == '/' ){
				if(one == '+' || one == '-'){
					//优先级大于栈顶,存入
					p->setData(cc);
					p->next = top->next;
					top->next = p;
				}else if(one == '*' || one == '/'){
					//优先级等于,弹出
					RESULT += pop(top); 
					p->setData(cc);
					p->next = top->next;
					top->next = p;
				}
			}
		}else{
			if(one == '('){
				//任何字符直接存进去
				 p->setData(cc);
				 p->next = top->next;
				 top->next = p;
			}else{	//	在括号里面已经存在有其他字符
			
				if(cc == '+' || cc == '-' ){
					//cc 优先级小于等于栈头 
					//将头出栈,再新的运算符入栈
					RESULT += pop(top); 
					 p->setData(cc);
					 p->next = top->next;
					 top->next = p;
					
				}else if(cc == '*' || cc == '/' ){
					if(one == '+' || one == '-'){
						p->setData(cc);
						p->next = top->next;
						top->next = p;
					}else if(one == '*' || one == '/'){
						RESULT += pop(top); 
						p->setData(cc);
						p->next = top->next;
						top->next = p;
					}
				}
			} 
		} 
	}
}

//输入一个中缀表达式
void input(Stack * top){
	string str;
	int idx = 0; 					//括号压栈 
	cout<<"cin:";
	cin>>str;
	for(int i=0;i<str.length();i++){
		if(str[i] >= '0' && str[i] <= '9'){
			//计算纯数字类型 
			if(IDX !=0 ){
				NUM_LEN ++;
			}		
			RESULT += str[i]; 		//遇到数字直接存进字符串 
		}else{
			push(top,str[i]);		//这种+-先压栈,遇到*/直接弹出 
		}
	}
} 

int main(int argc, char** argv) {
	//1.创建字符栈,存字符 
	Stack * top = new Stack;
	top->next = NULL;
	input(top);
	//出完输入之后就从栈内找继续出 
	getStacks(top);
	//展示最后的结果 
	resultView();
	return 0;
}
五、运行结果:

在这里插入图片描述在这里插入图片描述在这里插入图片描述

六、备注:

1.1 两个括号以上的中缀表达式会出错,像2+((10)/2+1)+4这种,2+(10)-(11)+3;这种
1.2 不是整数的数进行运算也会报错
1.3 这只是写了个思路以及代码实现

转载请说明出处!!!

发布了21 篇原创文章 · 获赞 2 · 访问量 6488

猜你喜欢

转载自blog.csdn.net/weixin_43386443/article/details/101782135