赞
踩
1.目的:
实现中缀表达式转为后缀,并计算得到计算结果输出显示。
2.输入输出介绍:
在英文输入下,键入你的表达式(注:这里只实现了 +-*/ 没有更复杂的幂次等计算)
之后,你将看到输出三部分:
①.将您输入的表达式的数字部分 和 操作符部分 分开,以独占一行的方式打印输出;
②.表达式的后缀输出;
③.计算结果。
3.完整代码,照例,无偿放在这里了:
- /*
- 1.要实现的目标是:根据输入的数学表达式,得到计算结果
- 2.分析:
- 数学表达式使用 字符串接受;
- 从表达式中摘出来需要得到数字部分;
- 需要两个栈
- 字符串类型的;一个栈用于中缀表达式转后缀;一个在后缀计算结果时候用
- */
-
- // 栈 先使用自定义实现;后面可以改成使用 STL容器
-
- #include<iostream>
- using namespace std;
- #include<string>
- #include<vector>
- #include<ctype.h> // 当判断的字符是数字时,函数返回1~9的非零值,当判断的字符不是数字时,函数返回 0
-
- // 自定义栈的数据结构
- typedef struct lNode{
- string data;
- struct lNode* next;
- }LNode, *LinkStack;
-
- // 初始化 构造成不带头结点的
- void init(LinkStack& s)
- {
- s = NULL;
- }
-
- // 判空
- bool isEmpty(LinkStack s)
- {
- if (s == NULL)
- return true;
- else
- {
- return false;
- }
- }
- // 进栈操作 为了方便对栈顶的操作 这里使用 --- 新元素 指向 老元素 --- 的结构
- void pushStack(LinkStack& s, string ele)
- {
- LNode* newNode = new LNode;
- newNode->data = ele;
- newNode->next = s;
-
- s = newNode; // 由于 要改变 栈顶指针的值 这里需要使用引用
- }
- // 出栈操作
- void popStack(LinkStack& s, string& ret)
- {
- if (isEmpty(s))
- {
- return;
- }
- ret = s->data;
-
- LNode* temp = s;
- s = s->next;
-
- delete temp;
- }
- // 读栈顶元素
- string getTop(LinkStack s)
- {
- if (!isEmpty(s))
- {
- return s->data;
- }
- }
- //销毁栈
- void destroyStack(LinkStack& s)
- {
- LNode* temp = s;
- while (temp != NULL)
- {
- LNode* nextNode = temp->next;
- delete temp;
- temp = nextNode;
- }
-
- s = NULL; // 将外部栈指针置为 NULL
- }
-
- // 获取用户输入
- string getExpression()
- {
- string expression;
- cout << "请输入您的表达式,以回车结束" << endl;
- getline(cin, expression);
-
- return expression;
- }
-
- // 中缀转后缀
- // 首先将 数字 与 +-*/ 操作符 区分出来,放入容器中,, 比如把 (32.1+2)*7/4 分成 ( 32.1 + 2 ) * 7 / 4
- vector<string> lookBetter(string expression)
- {
- vector<string> vS;
- string str;
- for (auto c : expression)
- {
- if (isdigit(c) || c =='.')
- {
- str += c;
- }
- else
- {
- if (!str.empty())
- {
- vS.push_back(str);
- str.clear();
- }
-
- if (c == ' ')
- {
- // 跳过空格
- continue;
- }
-
- str = c;
- vS.push_back(str);
- str.clear();
- }
- }
- if (!str.empty())
- {
- vS.push_back(str);
- str.clear();
- }
- return vS;
-
- }
-
- // 判断字符串 是否可以转成小数
- bool isNumber(const string& str) // 使用 const 限定不能修改; 使用引用直接在本体上操作,不需要复制一份,提高性能
- {
- try {
- stod(str); // 字符串 转 double类型
- return true;
- }
- catch(const invalid_argument& e)
- {
- return false;
- }
- catch (const out_of_range& e)
- {
- return false;
- }
- }
-
- // 中缀表达式 转后缀
- vector<string> mid2back(string expression)
- {
- LinkStack S;
- init(S);
-
- vector<string> ret;
-
- vector<string> vS = lookBetter(expression);
- for (vector<string>::iterator itBegin = vS.begin(); itBegin != vS.end(); itBegin++)
- {
- if (isNumber(*itBegin)) // 如果是数字部分 直接放入后缀容器
- {
- ret.push_back(*itBegin);
- }
- else
- {
- // 这里用的 string 类型,需要使用双引号
- if ((*itBegin) == "(") // 如果是"(" 直接入栈
- {
- pushStack(S, (*itBegin));
- }
- if ((*itBegin) == "+" || (*itBegin) == "-") // 如果是 "+"或"-" 将栈中遇到的所有+—*/ 出栈,,直到遇到第一个非 +—*/ ,,之后再将自己入栈
- {
- if (isEmpty(S))
- pushStack(S, (*itBegin));
- else
- {
- while (!isEmpty(S) && (getTop(S) == "+" || getTop(S) == "-" || getTop(S) == "*" || getTop(S) == "/"))
- {
- // 这里的非空判断是必要的 场景为 2+3-1 时 -将+出栈后,栈由非空变为空
- string popEle;
- popStack(S, popEle);
- ret.push_back(popEle);
- }
- pushStack(S, (*itBegin));
- }
- }
- if ((*itBegin) == "*" || (*itBegin) == "/") // 如果是 "*"或"/" 将栈中遇到的所有 */ 出栈,,直到遇到第一个非 */ ,,之后再将自己入栈
- {
- if (isEmpty(S))
- pushStack(S, (*itBegin));
- else
- {
- while (!isEmpty(S) && getTop(S) == "*" || getTop(S) == "/")
- {
- string popEle;
- popStack(S, popEle);
- ret.push_back(popEle);
- }
- pushStack(S, (*itBegin));
- }
- }
- if ((*itBegin) == ")") // 如果是")" 将遇到的"("之前的所有元素出栈放入后缀容器中,
- {
- string popEle;
- while (getTop(S) != "(")
- {
- popStack(S, popEle);
- ret.push_back(popEle);
- }
- popStack(S, popEle); // 将"(" 出栈,不添加到 后缀容器中 ")"不入栈
- }
- }
- }
-
- // 最后 如果 栈内非空,将栈中元素 出栈
- while (!isEmpty(S))
- {
- string popEle;
- popStack(S, popEle);
- ret.push_back(popEle);
- }
-
-
- return ret;
- }
-
- // 计算后缀表达式 得到正确结果
- double compute(vector<string> vS)
- {
- LinkStack S2;
- init(S2);
-
- for (vector<string>::iterator itBegin = vS.begin(); itBegin != vS.end(); itBegin++)
- {
- if (isNumber(*itBegin)) // 如果是数字 直接入栈
- {
- pushStack(S2, *itBegin);
- }
- else
- {
- string leftValue;
- string rightValue;
-
- popStack(S2, rightValue); // 先出栈的为右值
- popStack(S2, leftValue);
-
- if (*itBegin == "+")
- {
- double l = stod(leftValue);
- double r = stod(rightValue);
- pushStack(S2, to_string(l + r));
- }
- if (*itBegin == "-")
- {
- double l = stod(leftValue);
- double r = stod(rightValue);
- pushStack(S2, to_string(l - r));
- }
-
- if (*itBegin == "*")
- {
- double l = stod(leftValue);
- double r = stod(rightValue);
- pushStack(S2, to_string(l * r));
- }
- if (*itBegin == "/")
- {
- double l = stod(leftValue);
- double r = stod(rightValue);
- pushStack(S2, to_string(l / r));
- }
- }
- }
-
- if (!isEmpty(S2))
- {
- string ret;
- popStack(S2, ret);
- double retValue = stod(ret);
-
- return retValue;
- }
- }
-
-
- // 测试案例
- void test()
- {
- string expression = getExpression();
- vector<string> vS = lookBetter(expression);
- for (auto ele : vS)
- {
- cout << ele << endl;
- }
- cout << "----------------------" << endl;
- vector<string> mB = mid2back(expression);
- for (string ele : mB)
- {
- cout << ele<<" ";
- }
- cout << endl << "----------------------" << endl;
- double value = compute(mB);
-
- cout << "计算结果是:" << value << endl;
- }
-
-
- int main()
- {
-
- test();
-
- system("pause");
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。