中缀转后缀表达式并求值C++程序
- 格式:doc
- 大小:33.00 KB
- 文档页数:6
5 将中缀表达式转换为后缀表达式【问题描述】表达式转换。
输入的中缀表达式为字符串,转换得到的后缀表达式存入字符数组中并输出。
例如:a*(x+y)/(b-x) 转换后得:a x y + * b x - /【数据结构】●定义一个暂时存放运算符的转换工作栈opst。
●中缀表达式字符串char *infix;●后缀表达式字符串char *postfix;【算法提示】转换规则:把运算符移到它的两个操作数后面,删除掉所有的括号。
从头到尾扫描中缀表达式,对不同类型的字符按不同情况处理:●数字或小数点,直接写入字符串postfix,并在每个数值后面写入一个空格;●左括号,进栈,直到遇见相配的右括号,才出栈;●右括号,表明已扫描过括号内的中缀表达式,把从栈顶直到对应左括号之间的运算符依次退栈,并把结果推入栈内;●对于运算符,分两种情况处理:◆该运算符的优先级大于栈顶符号的优先级,则入栈;◆若该运算符的优先级小于栈顶优先级,则先弹出栈顶运算符、写入postfix串;继续将该运算符与栈顶运算符比较,直到能把它推入栈内为止(即优先级大于栈顶运算符)。
说明:自行设计运算符优先级的表示。
【主要代码】#include<iostream.h>#include<assert.h>#include<math.h>#include<string.h>const int stackIncreament=0;class opst{public:opst(int sz=50){maxSize=sz;top=-1;elements=new char[maxSize];assert(elements!=NULL);}~opst(){delete[]elements;}bool IsEmpty(){return (top==-1)?true:false;} bool IsFull(){return(top==maxSize-1)?true:false;}void Push( char &x);bool Pop(char &x);bool getTop(char &x);int getSize()const{return top+1;}void MakeEmpty(){top=-1;}void input();void Convert();friend ostream& operator<<(ostream &os,opst &s);private:char *elements;int top;int maxSize;void overflowProcess();};void opst::overflowProcess()//溢出处理{char *newArray=newchar[maxSize+stackIncreament];for(int i=0;i<=top;i++)newArray[i]=elements[i];maxSize=maxSize+stackIncreament; delete [] elements;elements=newArray;}void opst::Push(char &x){if(IsFull()==true) overflowProcess(); elements[++top]=x;}bool opst::Pop( char &x){if(IsEmpty()==true) return false;x=elements[top--];return true;}bool opst::getTop(char &x){if(IsEmpty()==true)return false;x=elements[top];return true;}ostream& operator<<(ostream &os,opst &s) {os<<"top=="<<s.top<<endl;for(int i=0;i<=s.top;i++)os<<s.elements[i];return os;}void opst::input(){char ch[20];cout<<"请输入中缀表达式(括号不能省略):"<<endl;cin.getline(ch,20);int i=0;while(ch[i]!='\0'){this->Push(ch[i]);i++;}ch[i]='#';}bool isdigit(char &x){if((x>='a'&&x<='z')||(x>='A'&&x<='Z')||(x>=' 0'&&x<='9'))return true;else return false;}int isp(char &x)//设置栈内优先级{switch(x){case '#':{return 0;break;}case '(':{return 1;break;}case '*':case '/':case '%':{return 5;break;}case '+':case '-':{return 3;break;}case ')':{return 6;break;}}}int icp(char &x)//设置栈外优先级{switch(x){case '#':{return 0;break;}case '(':{return 6;break;}case '*':case '/':case '%':{return 4;break;}case '+':case '-':{return 2;break;}case ')':{return 1;break;}}}void opst::Convert(){opst s;int i=0;char ch='#',ch1,op;s.Push(ch);this->Push(ch);elements[i];while(this->IsEmpty()==false&&elements[i]! ='#'){if(isdigit(elements[i])){cout<<elements[i];i++;}else{s.getTop(ch1);if(isp(ch1)<icp(elements[i])){s.Push(elements[i]);i++;}else if(isp(ch1)>icp(elements[i])){s.Pop(op);cout<<op;}else{s.Pop(op);if(op=='(') i++;}}}}void main(){opst a;a.input();cout<<"后缀表达式为:"<<endl;a.Convert();cout<<endl;}【实验过程】请输入中缀表达式(括号不能省略):(a+((b-c)/d))后缀表达式为:abc-d/+【实验体会】怎么样设置栈内外的优先级是解决这个程序的关键,我是用了开关语句来实现的。
C++实现中缀表达式转后缀表达式本⽂实例为⼤家分享了C++实现中缀表达式转后缀表达式的具体代码,供⼤家参考,具体内容如下⼀、思路:和中缀表达式的计算类似,只不过不⽤计算,把表达式输出即可1.⽤字符数组存储整⾏输⼊的中缀表达式;2.接着从字符数组的0位置开始判断字符,如果是数字,那就要判断后⾯是否是数字,如果是就不断扫描组成⼀个整数(暂不考虑负数和⼩数),最终组成⼀个整数,然后输出这个数(因为不⽤计算,所以直接输出即可);3.如果是左括号,直接进符号栈;4.如果是操作运算符,与符号栈的栈顶元素⽐较优先级:如果⾼就压⼊栈;低,就取出符号栈顶的元素输出;接着,再判断符号栈顶的元素和当前的运算符号继续⽐较优先级,重复前⾯步骤,直到栈空或者当前的符号优先级⾼;5.如果是右括号,把符号栈栈顶的元素取出,如果不是左括号,把取出的运算符输出,接着取符号栈栈顶的元素,直到符号栈中取出的符号是左括号;6.当扫描完字符数组时,判断符号栈是否为空:不为空,把符号栈栈顶的元素取出,输出到窗⼝,直到符号栈为空。
⼆、实现程序:// 中缀表达式转后缀表达式// 操作符:+、-、*、/、%// 输⼊:可以⽤cin.getline(arr, 250)或者cin.get(ch) && ch != '\n'// 测试数据:输⼊格式:(注意:不能有中⽂的操作符)// 2+(3+4)*5// 16+2*30/4// 输出格式:// 2 3 4 + 5 * +// 16 2 30 * 4 / +#include <iostream>#include <stack>// 判断是否是操作符bool isOperator(char ch) {if(ch == '+' || ch == '-' || ch == '*' || ch == '/')return true;return false; // 否则返回false}// 获取优先级int getPriority(char ch) {int level = 0; // 优先级switch(ch) {case '(':level = 1;break;case '+':case '-':level = 2;break;case '*':case '/':level = 3;break;default:break;}return level;}int main(int argc, const char * argv[]) {// insert code here...int num;char arr[250]; // ⼀个⼀个的读取表达式,直到遇到'\0'std::stack<char> op; // 栈op:存储操作符while(1) {std::cin.getline(arr,250);int len, i;char c; // c存储从栈中取出的操作符len = (int)strlen(arr); // strlen()输出的是:unsigned long类型,所以要强制转换为int类型i = 0;while(i < len) {if(isdigit(arr[i])) { // 如果是数字num = 0;do {num = num * 10 + (arr[i] - '0'); // ch - 48根据ASCAII码,字符与数字之间的转换关系i++; // 下⼀个字符}while(isdigit(arr[i]));std::cout << num << " ";} else if(arr[i] == '(') { // (:左括号op.push(arr[i]);i++;} else if(isOperator(arr[i])) { // 操作符if(op.empty()) {// 如果栈空,直接压⼊栈op.push(arr[i]);i++;}else {// ⽐较栈op顶的操作符与ch的优先级// 如果ch的优先级⾼,则直接压⼊栈// 否则,推出栈中的操作符,直到操作符⼩于ch的优先级,或者遇到(,或者栈已空while(!op.empty()) {c = op.top();if(getPriority(arr[i]) <= getPriority(c)) {// 优先级低或等于std::cout << c << " ";op.pop();} else // ch优先级⾼于栈中操作符break;} // while结束op.push(arr[i]); // 防⽌不断的推出操作符,最后空栈了;或者ch优先级⾼了i++;} // else} else if(arr[i] == ')') { // 如果是右括号,⼀直推出栈中操作符,直到遇到左括号(while(op.top() != '(') {std::cout << op.top() << " ";op.pop();}op.pop(); // 把左括号(推出栈i++;} else // 如果是空⽩符,就进⾏下⼀个字符的处理i++;} // 第⼆个while结束while(!op.empty()) { // 当栈不空,继续输出操作符std::cout << op.top() << " ";op.pop();}std::cout << std::endl;flush(std::cout);} // 第⼀个while结束return 0;}运⾏结果:以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
C++中缀转后缀表达式并求值//中缀转后缀#include<iostream>#include<stack>using namespace std;int prio(char x){if(x=='*'||x=='/') return2;if(x=='+'||x=='-') return1;if(x=='(') return0;else return -1;}void in_to_post(char* inorder,char* &post){stack<char>S;int k=0;while(*inorder){//数字if(*inorder>='0'&&*inorder<='9'){post[k++] = *inorder;}//操作符else{if(S.empty()) {S.push(*inorder);}else if(*inorder=='('){S.push(*inorder);}else if(*inorder==')'){while(S.top()!='('){post[k++]=S.top();S.pop();}S.pop();}else{while(prio(*inorder)<=prio(S.top())){post[k++]=S.top();S.pop();if(S.empty()) break;}S.push(*inorder);}}inorder++;}if(!S.empty()){char c =S.top();post[k++] = c;S.pop();}}//后缀表达式求值int cal(int a,int b,char c){if(c=='+') return a+b;else if(c=='-') return a-b;else if(c=='*') return a*b;else if(c=='/') return a/b;else return0;}int postcal(char* post){stack <int > s;while(*post){if(*post >='0'&& *post<='9'){s.push(*post);}else{int a = s.top()-48;s.pop();int b = s.top()-48;s.pop();int c = cal(b,a,*post);s.push(c+48);}post++;}return s.top()-48;}int main(){cout<<"输⼊中缀表达式:"<<endl;char* inorder =new char;cin>>inorder;char* post= new char;cout<<"后缀表达式为:";in_to_post(inorder,post);cout<<post<<endl;int res = postcal(post);cout<<"后缀表达式计算结果:"<<res<<endl;}求解思想:中缀转后缀表达式: 从左到右扫描输⼊的中缀表达式,若是数字,则直接输出到结果,若是运算符则判断: 1. ‘(’ :直接⼊栈; 2. ‘)’:依次把栈中的运算符输出到结果,知道出现‘(’,将左括号从栈中删除; 3. 若是其他运算符,判断当前运算符与栈顶元素的优先级(*/为2,+-为1,(为0,其他为-1),若是当前运算符优先级较⾼,则直接⼊栈,否则,依次输⼊⽐当前运算符优先级⾼或相等的运算符,知道遇到不符合条件的元素或者遇到左括号为⽌,再将当前运算符⼊栈。
c语言实现中缀表达式的计算要实现中缀表达式的计算,需要将中缀表达式转换为后缀表达式,然后再进行计算。
下面是一个使用C语言实现的示例代码,代码注释详细说明了每一步的操作。
```C#include <stdio.h>#include <stdbool.h>#include <stdlib.h>#include <ctype.h>#define STACK_SIZE 100//定义运算符栈结构typedef structchar stack[STACK_SIZE]; // 使用字符数组作为栈存储int top; // 栈顶指针} Stack;//初始化栈void initStack(Stack *s)s->top = -1;//判断栈是否为空bool isEmpty(Stack *s)return s->top == -1;//判断栈是否已满bool isFull(Stack *s)return s->top == STACK_SIZE - 1; //入栈void push(Stack *s, char c)if (isFull(s))printf("Stack overflow!");exit(1);}s->stack[++s->top] = c;//出栈,并返回栈顶元素char pop(Stack *s)if (isEmpty(s))printf("Stack underflow!");exit(1);}return s->stack[s->top--];//获取栈顶元素,不出栈char peek(Stack *s)if (isEmpty(s))printf("Stack underflow!");exit(1);}return s->stack[s->top];//判断运算符的优先级int precedence(char op)if (op == '+' , op == '-')return 1;} else if (op == '*' , op == '/')return 2;} elsereturn 0; // '('优先级最低}//中缀表达式转换为后缀表达式void infixToPostfix(char *infix, char *postfix) Stack s;initStack(&s);int i = 0; // 中缀表达式索引int j = 0; // 后缀表达式索引while (infix[i] != '\0')if (isdigit(infix[i]))postfix[j++] = infix[i++];} else if (infix[i] == '(')push(&s, infix[i++]);} else if (infix[i] == ')')while (!isEmpty(&s) && peek(&s) != '(') postfix[j++] = pop(&s);}if (isEmpty(&s) , peek(&s) != '(') printf("Invalid expression!");exit(1);}pop(&s); // 弹出'('i++;} else if (precedence(infix[i]))while (!isEmpty(&s) && precedence(peek(&s)) >= precedence(infix[i]))postfix[j++] = pop(&s);}push(&s, infix[i++]);} elseprintf("Invalid expression!");exit(1);}}while (!isEmpty(&s))if (peek(&s) == '(')printf("Invalid expression!");exit(1);}postfix[j++] = pop(&s);}postfix[j] = '\0';//计算后缀表达式的值int calculatePostfix(char *postfix) Stack s;initStack(&s);int i = 0;while (postfix[i] != '\0')if (isdigit(postfix[i]))push(&s, postfix[i++] - '0');} elseint operand2 = pop(&s);int operand1 = pop(&s);switch (postfix[i])case '+':push(&s, operand1 + operand2); break;case '-':push(&s, operand1 - operand2); break;case '*':push(&s, operand1 * operand2);break;case '/':push(&s, operand1 / operand2);break;}i++;}}return pop(&s);int mainchar infix[STACK_SIZE];char postfix[STACK_SIZE];printf("Please enter an infix expression: "); fgets(infix, sizeof(infix), stdin);infixToPostfix(infix, postfix);printf("Postfix expression: %s\n", postfix);printf("Result: %d\n", calculatePostfix(postfix)); return 0;```上述代码实现了在命令行接收用户输入的中缀表达式,将其转换为后缀表达式,并计算后缀表达式的值。
//ÈçºÎÓÃC++±àд¸ö³ÌÐòÖÐ׺±í´ïʽ±ä³Éºó׺±í´ïʽ£¬²¢Óúó׺±í´ïʽÇóÖµ#include <iostream>#include <string>#include <stack>#include <vector>namespace{class Expression{public:Expression();static void Remove_space(std::string &Translated);static int Compare(char op);static void RPN(std::string expression);static int Clculate();static void Display(const std::vector<int> &opnd, const std::string &soper);static std::vector<std::string> sResult;static std::stack<int> snum;};std::vector<std::string> Expression::sResult;std::stack<int> Expression::snum;Expression::Expression(){sResult.reserve(100);}void Expression::Remove_space(std::string &Translate){std::string::size_type position_start = 0;std::string::size_type position_end = 0;std::string Result;Result.reserve(100);while( (position_end = Translate.find_first_of(' ',position_start)) != std::string::npos){std::string temp = Translate.substr(position_start,position_end - position_start);Result += temp;position_start = ++position_end;}Result += Translate.substr(position_start,position_end - position_start);Translate = Result;}int Expression::Compare(char op){int Level = 0;switch(op){case '+':case '-':Level = 1;break;case '*':case '/':Level = 2;break;default:break;}return Level;}void Expression::RPN(std::string expression){std::string::size_type nCount = expression.length();std::string::size_type index = 0;std::stack<char> stmp;bool flag = false;stmp.push('@');while( index < nCount){if( expression[index] == '('){stmp.push('(');index++;}else if( expression[index] == ')'){while( stmp.top() != '('){sResult.push_back( std::string(1, stmp.top()) );stmp.pop();}stmp.pop();index++;}else if( expression[index] == '+' || expression[index] == '-' ||expression[index] == '*' || expression[index] == '/' ) {if( expression[index] == '-' || expression[index] == '+' ) {if(index == 0)//Èç¹ûµÚÒ»¸öÊý×ÖÊǸºÊý{index ++;flag = true;}else if( expression[index-1] == '(' )//Èç¹ûÀ¨ºÅÀïµÚÒ»¸öÊýÊǸºÊý{index++;flag = true;}else{while( Compare( expression[index] ) <= Compare( stmp.top() )){sResult.push_back( std::string(1, stmp.top()) );stmp.pop();}stmp.push( expression[index] );index++;}}else{while( Compare( expression[index] ) <= Compare( stmp.top() )){sResult.push_back( std::string(1, stmp.top()) );stmp.pop();}stmp.push( expression[index] );index++;}}else{std::string temp;if(flag == true){temp += expression[index - 1];flag = false;}while( expression[index] >= '0' && expression[index] <= '9') {temp += expression[index];index ++;}sResult.push_back( temp );}}//whilewhile(stmp.top() != '@'){if(stmp.top() == '('){std::cout << "Error in expression" << std::endl;exit(-1);}sResult.push_back( std::string(1, stmp.top()) );stmp.pop();}}//RPNint Expression::Clculate(){std::vector<int> opnd;size_t index = 0;int num1 = 0, num2 = 0;std::cout<< "OPNDÕ»" << "\t\t" <<"OPTRÕ»" << "\t\t" <<"ÊäÈë×Ö·û"<<"\t"<<"Ö÷Òª²Ù×÷"<<std::endl;for(index = 0; index < sResult.size(); ++index){std::string oper = sResult[index];if( (oper.size()>1) && (oper[0] == '+' || oper[0] == '-') ) {snum.push( atoi(sResult[index].c_str()) );opnd.push_back(atoi(sResult[index].c_str()));}else{switch(oper[0]){case '+':{num1 = snum.top();Display(opnd, sResult[index]);std::cout<< num1 << "\t\t" << num1<<" ³öOPNDÕ»";std::cout<< std::endl;snum.pop();opnd.pop_back();num2 = snum.top();Display(opnd, sResult[index]);std::cout<< num2 << "\t\t" << num2 <<" ³öOPNDÕ»";std::cout<< std::endl;snum.pop();opnd.pop_back();snum.push( num2 + num1);opnd.push_back(num2 + num1);Display(opnd, " ");std::cout<< "+" << "\t\t" << "¼ÆËã" << num2 << "+" << num1 << "²¢½«½á¹ûѹOPNDÕ»";std::cout<< std::endl;}break;case '-':{num1 = snum.top();Display(opnd, sResult[index]);std::cout<< num1 << "\t\t" << num1<<" ³öOPNDÕ»";std::cout<< std::endl;snum.pop();opnd.pop_back();num2 = snum.top();Display(opnd, sResult[index]);std::cout<< num2 << "\t\t" << num2 <<" ³öOPNDÕ»";std::cout<< std::endl;snum.pop();opnd.pop_back();snum.push( num2 - num1);opnd.push_back(num2 - num1);Display(opnd, " ");std::cout<< "+" << "\t\t" << "¼ÆËã" << num2 << "-" << num1 << "²¢½«½á¹ûѹOPNDÕ»";std::cout<< std::endl;}break;case '*':{num1 = snum.top();Display(opnd, sResult[index]);std::cout<< num1 << "\t\t" << num1<<" ³öOPNDÕ»";std::cout<< std::endl;snum.pop();opnd.pop_back();num2 = snum.top();Display(opnd, sResult[index]);std::cout<< num2 << "\t\t" << num2 <<" ³öOPNDÕ»";std::cout<< std::endl;snum.pop();opnd.pop_back();snum.push( num2 * num1);opnd.push_back(num2 * num1);Display(opnd, " ");std::cout<< "+" << "\t\t" << "¼ÆËã" << num2 << "*" << num1 << "²¢½«½á¹ûѹOPNDÕ»";std::cout<< std::endl;}break;case '/':{num1 = snum.top();Display(opnd, sResult[index]);std::cout<< num1 << "\t\t" << num1<<" ³öOPNDÕ»";std::cout<< std::endl;snum.pop();opnd.pop_back();num2 = snum.top();Display(opnd, sResult[index]);std::cout<< num2 << "\t\t" << num2 <<" ³öOPNDÕ»";std::cout<< std::endl;snum.pop();opnd.pop_back();if(num1 == 0){std::cerr << "Expression worng!" << std::endl;exit(-1);}snum.push( num2 / num1);opnd.push_back(num2 / num1);Display(opnd, " ");std::cout<< "+" << "\t\t" << "¼ÆËã" << num2 << "*" << num1 << "²¢½«½á¹ûѹOPNDÕ»";std::cout<< std::endl;}break;default:{snum.push( atoi(sResult[index].c_str()) );opnd.push_back( atoi(sResult[index].c_str()) );}break;}//swith}}//whileint result = snum.top();snum.pop();return result;}void Expression::Display(const std::vector<int> &opnd, const std::string &soper){size_t index = 0;for(index; index< opnd.size(); index++){std::cout << opnd[index] << " ";}std::cout<< "\t\t" << soper << "\t\t";}}//classint main(){std::string Input;std::cout << "please input the expression (Enter key for end)" << std::endl;std::getline(std::cin, Input, '\n');Expression expression;Expression::Remove_space(Input);Expression::RPN(Input);std::cout << std::endl;std::cout << "ºó׺±í´ïʽ:" << std::endl;for(size_t index = 0; index < Expression::sResult.size(); ++index) {std::cout << Expression::sResult[index] << " ";}std::cout << std::endl;std::cout<< Expression::Clculate() << std::endl;return 0;}/*please input the expression (Enter key for end)11-(22-11)*2-(-10)+10/5ºó׺±í´ïʽ:11 22 11 - 2 * - -10 - 10 5 / +OPNDÕ» OPTRÕ» ÊäÈë×Ö·û Ö÷Òª²Ù×÷11 22 11 - 11 11 ³öOPNDÕ»11 22 - 22 22 ³öOPNDÕ»11 11 + ¼ÆËã22-11²¢½«½á¹ûѹOPNDÕ»11 11 2 * 2 2 ³öOPNDÕ»11 11 * 11 11 ³öOPNDÕ»11 22 + ¼ÆËã11*2²¢½«½á¹ûѹOPNDÕ» 11 22 - 22 22 ³öOPNDÕ»11 - 11 11 ³öOPNDÕ»-11 + ¼ÆËã11-22²¢½«½á¹ûѹOPNDÕ»-11 -10 - -10 -10 ³öOPNDÕ»-11 - -11 -11 ³öOPNDÕ»-1 + ¼ÆËã-11--10²¢½«½á¹ûѹOPNDÕ» -1 10 5 / 5 5 ³öOPNDÕ»-1 10 / 10 10 ³öOPNDÕ»-1 2 + ¼ÆËã10*5²¢½«½á¹ûѹOPNDÕ»-1 2 + 2 2 ³öOPNDÕ»-1 + -1 -1 ³öOPNDÕ»1 + ¼ÆËã-1+2²¢½«½á¹ûѹOPNDÕ»1Press any key to continu*/。
中缀表达式求值(C++实现)当初的数据结构上机作业,题⽬很奇葩,要求先将中缀表达式转换成后缀表达式再求值。
只加⼊了⼀些错误判断,因为输⼊的错误形式太多了,做到⼀半懒得做了。
代码:展开1// 中缀表达式求值(通过先转换为后缀表达式再求值)2// 作者:王锦3// 邮箱:jinksw@45 #include "stdafx.h"6 #include <stack>7 #include <queue>8 #include <iostream>9 #include <sstream>10using namespace std;1112class IEcalculator//中缀表达式求值13 {14private:15 stack<double> s;16 queue<string> suffixE;//⽤于存储后缀表达式序列17 stack<char> operatorStack;18bool flag;//⽤于记录是否发⽣错误,避免不必要的计算19bool aIsNotLessThenB(char a,char b);//⽤于判断a的优先级是否⼤于等于b20bool getTwoOperands(double &opd1,double &opd2);21bool compute(char op);22void clear()//清除栈中元素23 {24while(!s.empty())25 s.pop();26while(!suffixE.empty())27 suffixE.pop();28while(!operatorStack.empty())29 operatorStack.pop();30 }31void calculateSE();32public:33void calculate();34 };35bool IEcalculator::getTwoOperands(double &opd1,double &opd2)36 {37if(s.empty())38 {39 cerr << "操作数缺失,请检查输⼊表达式!" << endl;40return false;41 }42 opd1 = s.top();43 s.pop();44if(s.empty())45 {46 cerr << "操作数缺失,请检查输⼊表达式!" << endl;47return false;48 }49 opd2 = s.top();50 s.pop();51return true;52 }5354bool IEcalculator::compute(char op)55 {56double opd1,opd2;57if(getTwoOperands(opd1,opd2))58 {59switch (op)60 {61case'+':62 s.push(opd2 + opd1);63break;64case'-':65 s.push(opd2 - opd1);66break;67case'*':68 s.push(opd2 * opd1);69break;70case'/':71if(abs(opd1) < 1E-7)73 cerr << "除数不能为0,请检查表达式" << endl;74 clear();75return false;76 }77 s.push(opd2 / opd1);78break;79default:80break;81 }82 }83else84 {85 clear();86return false;87 }88 }8990void IEcalculator::calculateSE()91 {92string expressionStream;93while(!suffixE.empty())94 {95 expressionStream+=""+suffixE.front();96 suffixE.pop();97 }98 expressionStream += "=";99 istringstream iss(expressionStream,istringstream::in);//将expressionStream作为输⼊流100char c;101double newOperand,result;102bool isRight = true;//compute(c)函数返回标志,若出现除数为0错误,则不再计算103while(iss >> c, isRight && c != '=')104 {105switch (c)106 {107case'+':108case'-':109case'*':110case'/':111 isRight = compute(c);112break;113default:114 iss.putback(c);115 iss >> newOperand;116 s.push(newOperand);117break;118 }119 }120if(isRight)121 {122 result = s.top();123 s.pop();124if(s.empty())125 cout << "result = " << result << endl;126else127 {128 cerr << "表达式操作数剩余!" << endl;129 }130 clear();131 }132else133 {134 clear();135 }136 }137bool IEcalculator::aIsNotLessThenB(char a,char b)138 {139switch (a)140 {141case'(':142return true;143case'+':144case'-':145switch (b)146 {147case'(':148case'*':149case'/':150return false;151default:152return true;153break;154 }155case'*':157switch (b)158 {159case'(':160return false;161default:162return true;163break;164 }165default:166break;167 }168 }169void IEcalculator::calculate()170 {171 flag = true;172double newOperand;173string tempStr = "";//⽤于将字符转换为字符串174char c;175while(cin >> c,c != '=' && flag)176 {177switch (c)178 {179case'+':180case'-':181case'*':182case'/':183while(!operatorStack.empty() && aIsNotLessThenB(operatorStack.top 184185 (),c) &&operatorStack.top() != '(')186 {187 suffixE.push(operatorStack.top()+tempStr);188 operatorStack.pop();189 }190 operatorStack.push(c);191break;192case'(':193 operatorStack.push(c);194break;195case')':196while(!operatorStack.empty() && operatorStack.top() != '(')197 {198 suffixE.push(operatorStack.top()+tempStr);199 operatorStack.pop();200 }201if(operatorStack.empty())//此时栈空则错误202 {203 flag = false;204 clear();205break;206 }207 operatorStack.pop();208break;209default:210 cin.putback(c);211 cin >> newOperand;212string str;213 stringstream ss;214 ss<<newOperand;215 ss>>str;216 suffixE.push(string(str));217break;218 }219 }220while(!operatorStack.empty())221 {222if(operatorStack.top() == '(')223 {224 flag = false;225break;226 }227 suffixE.push(operatorStack.top()+tempStr);228 operatorStack.pop();229 }230if(flag)231 {232 calculateSE();233 }234else235 cerr << "表达式输⼊有误,请重试" << endl;236 clear();237 }238239int _tmain(int argc, _TCHAR* argv[])240 {241 cout << "请输⼊中缀表达式,以=结束:(q退出)" << endl; 242char c;243 cin >> c;244while(c != 'q')245 {246 cin.putback(c);247 IEcalculator test;248 test.calculate();249 cout << "请输⼊中缀表达式,以=结束:(q退出)" << endl; 250 cin >> c;251 }252253 }。
中缀表达式转后缀表达式中缀表达式转后缀表达式的规则。
1.遇到操作数:直接输入到后缀表达式栈2.遇到运算符,直接入操作符栈3.遇到左括号:直接将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈6.最终将操作符栈中的元素依次出栈,输出到后缀表达式栈。
以下是自己写的代码。
亲测没有问题。
(模拟一个计算器,可以带括号,中间可以空格,只支持整数输入,但是输出结果精确到小数后6位)#include "stdio.h"#define MAX_LEN 100typedef struct cal{unsigned char isOper;//是否是操作数1,操作符0.操作数double Num; //值。
或者是操作符的ASCII值}STRUCT_CAL;#define IS_NUM 0x00#define IS_OPER 0x01STRUCT_CAL stackCal[MAX_LEN];STRUCT_CAL stackCalBack[MAX_LEN];unsigned char topCal;char stackOper[MAX_LEN];unsigned char topOper;/****************************************************************** 堆栈初始化*****************************************************************/void stackInit(void){int i;for(i=0;i<MAX_LEN;i++){stackCal[i].isOper = 0;stackCal[i].Num = 0;stackOper[i] = 0;}topCal = topOper = 0;}/***************************************************************** * 返回堆栈的栈顶,返回后栈顶减一*****************************************************************/ STRUCT_CAL * stackCalPop(void){if(topCal == 0)return (STRUCT_CAL *)0;return stackCal+(--topCal);}/***************************************************************** * 计算表达式入栈*****************************************************************/void stackCalPush(double num, unsigned char isOper){if(topCal>=MAX_LEN)return;stackCal[topCal].Num = num;stackCal[topCal].isOper= isOper;topCal++;}/***************************************************************** * 操作符出栈*****************************************************************/char stackOperPop(void){if(topOper == 0)return 0;return stackOper[--topOper];}/****************************************************************** 操作符入栈*****************************************************************/void stackOperPush(char oper){if(topOper >=MAX_LEN)return;stackOper[topOper++] = oper;}/****************************************************************** 比较两个sour sour1 的优先级* 1 sour >= sour1 直接入操作符栈* 0 sour < sour1 直接入计算表达式栈*****************************************************************/ unsigned char comparPrior(char sour, char sour1){if(sour =='\0' ||sour1 == '\0') return 1;switch(sour){case '+':case '-':if(sour1 == '*' ||sour1 == '/'||sour1 == '+' ||sour1 == '-' ){return 0;}else{return 1;}break;case '*':case '/':if(sour1 == '*' ||sour1 == '/'||sour1 == '+' ||sour1 == '-'||sour1 == '('){return 1;}else{return 0;}break;default:return 1;break;}}/****************************************************************** 将输入的字符串转换为栈*****************************************************************/void StrToCal(char *pStr){int tmpNum = 0;char tmpOper;char islastNum = 0;//判断上一个字符是什么。
一、设计思想计算算术表达式可以用两种方法实现:1.中缀转后缀算法此算法分两步实现:先将算术表达式转换为后缀表达式,然后对后缀表达式进行计算。
具体实现方法如下:(1)中缀转后缀需要建一个操作符栈op和一个字符数组exp,op栈存放操作符,字符数组用来存放转换以后的后缀表达式。
首先,得到用户输入的中缀表达式,将其存入str数组中。
对str数组逐个扫描,如果是数字或小数点,则直接存入exp数组中,当扫描完数值后,在后面加一个#作为分隔符。
如果是操作符,并且栈为空直接入栈,如果栈不为空,与栈顶操作符比较优先等级,若比栈顶优先级高,入栈;如果比栈顶优先级低或相等,出栈将其操作符存到exp数组中,直到栈顶元素优先等级低于扫描的操作符,则此操作符入栈;如果是左括号,直接入栈,如果是右括号,出栈存入exp数组,直到遇到左括号,左括号丢掉。
然后继续扫描下一个字符,直到遇到str中的结束符号\0,扫描结束。
结束后看op栈是否为空,若不为空,继续出栈存入exp数组中,直到栈为空。
到此在exp数组最后加结束字符\0。
我们就得到了后缀表达式。
(2)后缀表达式计算此时需要一个数值栈od来存放数值。
对exp数组进行逐个扫描,当遇到数字或小数点时,截取数值子串将其转换成double类型的小数,存入od栈中。
当遇到操作符,从栈中取出两个数,进行计算后再放入栈中。
继续扫描,知道扫描结束,此时值栈中的数值就是计算的结果,取出返回计算结果。
2.两个栈实现算法此算法需要两个栈,一个值栈od,一个操作符栈op。
将用户输入的数学表达式存入str数组中,对其数组进行逐个扫描。
当遇到数字或小数点,截取数值子串,将其转换成double类型的数值存入od栈中;当遇到左括号,直接入op栈;遇到右括号,op栈出栈,再从值栈od中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到操作符栈栈顶为左括号,将左括号丢掉。
如果遇到操作符,若op栈为空,直接入栈;若栈不为空,与栈顶元素比较优先等级,若比栈顶操作符优先等级高,直接入op栈,如果低于或等于栈顶优先等级,op栈出栈,再从值栈中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到栈顶优先等级低于扫描的操作符等级,将此操作符入op栈。
c语言中缀表达式转后缀表达式在C语言中,可以使用栈的数据结构来实现中缀表达式转后缀表达式的操作。
下面是一个示例代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX_SIZE 100// 定义运算符的优先级int getPriority(char operator) {switch(operator) {case '+':case '-':return 1;case '*':case '/':return 2;case '^':return 3;default:return 0;}}// 判断字符是否为操作符int isOperator(char character) {return (character == '+' || character == '-' || character == '*' ||character == '/' || character == '^');}// 中缀表达式转后缀表达式void infixToPostfix(char* infixExpression, char* postfixExpression) {char stack[MAX_SIZE];int top = -1;int infixLength = strlen(infixExpression);int postfixIndex = 0;for(int i = 0; i < infixLength; i++) {// 如果是操作数,直接输出到后缀表达式if(!isOperator(infixExpression[i]) && infixExpression[i] != '(' && infixExpression[i] != ')') {postfixExpression[postfixIndex] = infixExpression[i];postfixIndex++;}// 如果是‘(’,入栈if(infixExpression[i] == '(') {stack[++top] = infixExpression[i];}// 如果是操作符if(isOperator(infixExpression[i])) {// 当当前操作符的优先级小于等于栈顶操作符的优先级时,将栈顶操作符输出到后缀表达式,再将当前操作符入栈 while(top != -1 && getPriority(infixExpression[i]) <=getPriority(stack[top])) {postfixExpression[postfixIndex] = stack[top];postfixIndex++;top--;}stack[++top] = infixExpression[i];}// 如果是')',将栈中的操作符输出到后缀表达式直到遇到‘(’if(infixExpression[i] == ')') {while(top != -1 && stack[top] != '(') {postfixExpression[postfixIndex] = stack[top];postfixIndex++;top--;}// 弹出‘(’top--;}}// 输出栈中剩余的操作符while(top != -1) {postfixExpression[postfixIndex] = stack[top];postfixIndex++;top--;}postfixExpression[postfixIndex] = '\0';}int main() {char infixExpression[MAX_SIZE];char postfixExpression[MAX_SIZE];printf("请输入中缀表达式:");scanf("%s", infixExpression);infixToPostfix(infixExpression, postfixExpression);printf("后缀表达式:%s\n", postfixExpression);return 0;}```该程序通过读入一个中缀表达式,将其转换为后缀表达式并输出。