PHP速学视频免费教程(入门到精通)
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
该计算器程序使用中缀表达式转后缀表达式的策略,并通过栈实现计算;其核心步骤为:1.定义运算符优先级函数precedence;2.实现中缀转后缀函数infixtopostfix,利用栈处理运算符并生成后缀队列;3.实现后缀表达式求值函数evaluatepostfix,用栈存储操作数并根据运算符执行计算;4.主函数main接收输入并调用上述函数,同时捕获和处理异常;5.空格处理依赖stringstream自动忽略并分割token;6.扩展新运算符需在precedence添加优先级并在evaluatepostfix的switch中添加逻辑;7.支持函数调用需增加函数注册表、修改infixtopostfix识别函数名、并在evaluatepostfix中调用对应函数。
用C++实现一个简单的计算器,核心在于解析用户输入的字符串,识别数字和运算符,然后按照运算优先级进行计算。 这听起来简单,但细节很多,比如错误处理、不同数据类型的兼容性等等。
解决方案
首先,我们需要一个主函数来接收用户的输入,并调用相应的函数进行处理。
#include <iostream> #include <string> #include <stack> #include <queue> #include <sstream> #include <cctype> #include <stdexcept> #include <cmath> using namespace std; // 定义运算符优先级 int precedence(char op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/') return 2; if (op == '^') // 指数运算 return 3; return 0; } // 中缀表达式转后缀表达式 queue<string> infixToPostfix(const string& expression) { queue<string> postfixQueue; stack<char> operatorStack; stringstream ss(expression); string token; while (ss >> token) { if (isdigit(token[0]) || (token.size() > 1 && isdigit(token[1]) && (token[0] == '-' || token[0] == '+'))) { // 数字直接入队列 (处理负数) postfixQueue.push(token); } else if (token == "(") { operatorStack.push('('); } else if (token == ")") { while (!operatorStack.empty() && operatorStack.top() != '(') { postfixQueue.push(string(1, operatorStack.top())); operatorStack.pop(); } if (!operatorStack.empty() && operatorStack.top() == '(') { operatorStack.pop(); // 弹出 '(' } else { throw invalid_argument("Mismatched parentheses"); // 括号不匹配 } } else { // 运算符处理 char op = token[0]; // 假设token长度为1 while (!operatorStack.empty() && precedence(op) postfixQueue) { stack<double> operandStack; while (!postfixQueue.empty()) { string token = postfixQueue.front(); postfixQueue.pop(); if (isdigit(token[0]) || (token.size() > 1 && isdigit(token[1]) && (token[0] == '-' || token[0] == '+'))) { // 数字入栈 operandStack.push(stod(token)); } else { // 运算符处理 if (operandStack.size() postfixQueue = infixToPostfix(expression); double result = evaluatePostfix(postfixQueue); cout <p>这段代码首先定义了运算符的优先级,然后实现了一个中缀表达式转后缀表达式的函数<pre class="brush:php;toolbar:false">infixToPostfix,最后实现了一个计算后缀表达式的函数
evaluatePostfix。 主函数负责接收用户输入,调用这两个函数,并输出结果。当然,这段代码还包含了一些错误处理,比如括号不匹配、除数为零等等。
在上面的代码中,我们使用了
stringstream来处理用户输入。
stringstream会自动忽略空格,并将字符串分割成一个个的 token。 因此,用户可以在输入表达式时随意添加空格,程序仍然可以正确解析。
要添加更多运算符,首先需要在
precedence函数中定义新运算符的优先级。 然后,在
evaluatePostfix函数的
switch语句中添加新运算符的处理逻辑。 例如,要添加求模运算符
%,可以这样修改代码:
// 在 precedence 函数中添加 % 的优先级 int precedence(char op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/') return 2; if (op == '%') // 求模运算 return 2; if (op == '^') // 指数运算 return 3; return 0; } // 在 evaluatePostfix 函数的 switch 语句中添加 % 的处理逻辑 switch (op) { case '+': operandStack.push(operand1 + operand2); break; case '-': operandStack.push(operand1 - operand2); break; case '*': operandStack.push(operand1 * operand2); break; case '/': if (operand2 == 0) { throw invalid_argument("Division by zero"); // 除数为零 } operandStack.push(operand1 / operand2); break; case '%': if (operand2 == 0) { throw invalid_argument("Division by zero"); // 除数为零 } operandStack.push(fmod(operand1, operand2)); // 使用 fmod 处理浮点数求模 break; case '^': operandStack.push(pow(operand1, operand2)); break; default: throw invalid_argument("Invalid operator"); // 无效运算符 }
注意,求模运算需要使用
fmod函数来处理浮点数。
处理包含函数调用的表达式会更复杂。 首先,需要在
infixToPostfix函数中识别函数名和参数。 然后,在
evaluatePostfix函数中调用相应的函数,并将结果压入栈中。 这需要一个函数注册表,将函数名和函数指针关联起来。 例如:
#include <map> // 定义函数指针类型 typedef double (*FunctionPtr)(double); // 函数注册表 map<string functionptr> functionTable; // 注册函数 void registerFunction(const string& name, FunctionPtr function) { functionTable[name] = function; } // 实现一个示例函数 double sine(double x) { return sin(x); } int main() { // 注册 sine 函数 registerFunction("sin", sine); // ... (修改 infixToPostfix 和 evaluatePostfix 函数) return 0; }</string></map>
然后,需要修改
infixToPostfix函数,识别函数调用,并将函数名和参数转换为后缀表达式。 例如,将
sin(3.14)转换为
3.14 sin。 最后,修改
evaluatePostfix函数,当遇到函数名时,从函数注册表中查找函数指针,并调用该函数。 这部分代码比较复杂,需要仔细设计和实现。
C++免费学习笔记(深入):立即学习
>在学习笔记中,你将探索 C++ 的入门与实战技巧!