一、功能实现:
输入正常的中缀表达式,通过程序实现转化成后缀表达式,并且输出结果。
二、思路分析:
1. 输入:三个示例
2+4x6-8/2+5
2+(3x4)-5+1
3+(11)*2-62. 分析:
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 这只是写了个思路以及代码实现
转载请说明出处!!!