建手机网站教程百度seo优化软件
建手机网站教程,百度seo优化软件,温州设计集团,广州新建站点击 C 语言编程核心突破 快速C语言入门 通过中缀表达式转换后缀表达式, 用C语言完成一个简单的计算器 前言一、中缀表达式和后缀表达式 (AI辅助)二、中缀转后缀规则及后缀运算规则 (AI辅助)总结 前言
要解决问题: 在练习用Qt完成一个简单的计算器时, 需要将一个文本… 点击 C 语言编程核心突破 快速C语言入门 通过中缀表达式转换后缀表达式, 用C语言完成一个简单的计算器 前言一、中缀表达式和后缀表达式 (AI辅助)二、中缀转后缀规则及后缀运算规则 (AI辅助)总结 前言
要解决问题: 在练习用Qt完成一个简单的计算器时, 需要将一个文本计算式转换为C语言可使用的模式, 即后缀表达式, 规则还是挺繁复的.
想到的思路: 查文档, 了解中缀表达式转换为后缀表达式.
其它的补充: 需要用到栈, 这个基本功一定要扎实. 一、中缀表达式和后缀表达式 (AI辅助)
中缀表达式是指常见的数学表达式如 2 3 * 4 - 5其中运算符位于操作数之间。
中缀表达式通常需要通过加入括号来明确运算顺序。
后缀表达式也称为逆波兰表达式是一种不需要括号的表达式表示方式其中运算符位于其相应的操作数之后。
例如上述中缀表达式的后缀形式为 2 3 4 * 5 -
在计算机科学中后缀表达式比中缀表达式更容易被计算机算法处理和计算因为它们没有嵌套括号的优先级问题。
因此在编写计算机程序解析表达式时通常会将中缀表达式转换为等效的后缀表达式以便更轻松地处理它们。
二、中缀转后缀规则及后缀运算规则 (AI辅助)
在后缀表达式中运算符总是在它们所操作的两个操作数之后出现。
例如对于后缀表达式 “3 4 5 *”运算规则如下 先将操作数 3 和 4 压入栈中。 遇到 “” 运算符弹出栈顶的 3 和 4 进行加法运算结果为 7再将结果 7 压入栈中。 遇到操作数 5将其压入栈中。 遇到 “*” 运算符弹出栈顶的 7 和 5 进行乘法运算结果为 35再将结果 35 压入栈中。 后缀表达式中的所有元素都被处理后栈中只剩下一个元素 35即为后缀表达式的计算结果。
具体规则见代码注释:
#include ctype.h
#include stdio.h
#include stdlib.h
#include string.h// 节点
struct node
{int flag;int value;struct node *next;
};// 栈
typedef struct node *Stack;// 压栈
void push(Stack *stack, int flag, int value)
{struct node *head malloc(sizeof(struct node));head-flag flag;head-value value;head-next *stack;*stack head;
}// 出栈
int pop(Stack *stack)
{int rest (*stack)-value;Stack temp *stack;*stack (*stack)-next;free(temp);return rest;
}// 判断栈是否为空
int empty(Stack *stack)
{return (*stack) NULL;
}// 栈顶元素
int top(Stack *stack)
{int rest (*stack)-value;return rest;
}// 栈顶flag
int topFlag(Stack *stack)
{return (*stack)-flag;
}// 释放栈
void freeStack(Stack *stack)
{while (*stack){struct node *head *stack;*stack (*stack)-next;free(head);}
}// 反转栈
void reverse(Stack *stack)
{if (!(*stack)){return;}Stack head;Stack tail NULL;while (*stack){head *stack;*stack (*stack)-next;head-next tail;tail head;}*stack head;
}// 返回优先级
int priority(char operate)
{switch (operate){case :case -:return 1;case *:case /:case %:return 2;default:return 0;}
}// 判断操作符
int isOperator(char operator)
{return (operator || operator - || operator * || operator/ ||operator %);
}// 判断左括号
int isLeftParenthesis(char operator)
{return operator (;
}// 判断右括号
int isRightParenthesis(char operator)
{return operator );
}// 中缀表达式转后缀表达式的规则如下
void convertToPostfix(char *input, Stack *postfix)
{Stack operateStack NULL;static char number[32];// 1.从左到右遍历中缀表达式的每个元素。for (int i 0; input[i] ! \0; i){// 2.如果当前元素是数字则将其加入后缀表达式中。if (isdigit(input[i])){int num 0;while (isdigit(input[i])){number[num] input[i];}number[num] \0;i--;push(postfix, 1, atoi(number));}// 3.如果当前元素是操作符则执行以下步骤// a.如果该操作符是左括号“”则将其加入操作符栈中。else if (isLeftParenthesis(input[i])){push(operateStack, 0, input[i]);}// b.如果该操作符是右括号“”则将操作符栈中的操作符弹出并加入后缀表达式中直到遇到左括号为止。else if (isRightParenthesis(input[i])){while (!isLeftParenthesis((char)top(operateStack))){push(postfix, 0, pop(operateStack));}pop(operateStack);}else if (isOperator(input[i])){// c.如果该操作符的优先级比操作符栈顶操作符的优先级低或相等// 则将操作符栈中的操作符弹出并加入后缀表达式中// 直到不存在比当前操作符优先级高的操作符为止。while (!empty(operateStack) priority(input[i]) priority((char)top(operateStack))){push(postfix, 0, pop(operateStack));}// 将当前操作符加入操作符栈中。// d.如果该操作符的优先级比操作符栈顶操作符的优先级高则将当前操作符加入操作符栈中。push(operateStack, 0, input[i]);}}// 4.当中缀表达式遍历完后将操作符栈中的所有操作符依次弹出并加入后缀表达式中。while (!empty(operateStack)){push(postfix, 0, pop(operateStack));}freeStack(operateStack);reverse(postfix);
}// 计算
int calculate(int operand1, int operand2, char operate)
{switch (operate){case :return operand1 operand2;case -:return operand1 - operand2;case *:return operand1 * operand2;case /:return operand1 / operand2;case %:return operand1 % operand2;default:return 0;}
}// 计算后缀表达式的规则如下
int evaluatePostfix(Stack *postfix)
{Stack stack NULL;// 1.从左到右扫描后缀表达式。while (*postfix){// 2.遇到操作数时将其压入操作数栈中。if ((*postfix)-flag){push(stack, 1, pop(postfix));}// 3.遇到运算符时弹出栈顶的两个操作数执行该运算符的计算并将结果压入操作数栈中。else if (!(*postfix)-flag){int operand2 pop(stack);int operand1 pop(stack);int result calculate(operand1, operand2, (char)pop(postfix));push(stack, 1, result);}}// 4.重复上述过程直到后缀表达式中的所有元素都被处理。// 5.最后操作数栈中只剩下一个数即为后缀表达式的计算结果。int result pop(stack);freeStack(stack);return result;
}// 打印后缀表达式栈
void printStack(Stack stack)
{while (stack){if (stack-flag){printf(%d , stack-value);stack stack-next;}else{printf(%c , stack-value);stack stack-next;}}printf(\n);
}// 测试
int main()
{char input[128];Stack postfix NULL;printf(请输入含加减乘除、求模及括号的复杂算式);scanf(%s, input);convertToPostfix(input, postfix);printf(后缀表达式为\n);printStack(postfix);int result evaluatePostfix(postfix);printf(计算结果为%d\n, result);freeStack(postfix);return 0;
}总结
用C语言对字符串算式做语法分析并得出计算结果, 是很多教材的标准示例, 但并不简单, 属于数据结构和算法的一个类型, 考验栈结构和操作函数, 中缀转后缀算法, 后缀计算算法等, 慢慢体会. 点击 C 语言编程核心突破 快速C语言入门
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88576.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!