C语言实现表达式求值,支持+、-、*、/四则运算,并且支持多级括号,自定义了栈的操作。
来源:互联网 发布:三维建筑物重建软件 编辑:程序博客网 时间:2024/05/23 11:26
<span style="color: rgb(51, 255, 51); font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">以下是代码的实现使用gcc已经成功运行了,下面是效果图</span>
#include <stdio.h>#include <stdlib.h>#define N 50 //定义接收字符串大小typedef struct _node_ { int num_ch; //数字和符号都用int存储 struct _node_ *next;}node;/*** 创建一个链栈** 注意我的栈最后一个元素无意义但必须存在** 因为方便在表达式末尾进行操作*/node *CreatNode(){ node *head = (node *)malloc(sizeof(node)); if(NULL == head) return NULL; head->num_ch = 0; head->next = NULL; return head;}/*** 压栈** 直接给最后一个元素赋值** 并新建一个无意义的结点作为最后元素*/int push(node *p,int num){ while(NULL != p->next) { p = p->next; } p->num_ch = num; node *q = (node *)malloc(sizeof(node)); q->num_ch = 0; q->next = NULL; p->next = q; return 0;}/*** 弾栈** 最后一个无意义的直接free** 倒数第二个next置空,返回倒数第二的值*/int pop(node *p){ int tmp; if(NULL == p->next) return -1;//只有头,无值时无法pop while(NULL != p->next->next) { p = p->next; } tmp = p->num_ch; free(p->next); p->num_ch = 0; p->next = NULL; return tmp;}/*** 获取栈顶元素*/int gettop(node *p){while(NULL != p->next->next) {p = p->next;}return p->num_ch;}/*** 判栈空** 如果只剩一个结点(这是个无意义的)** 那么就为空*/int isEmpty(node *p){ if(NULL == p->next) return 1; return 0;}/*** 显示栈的所有元素*/void show(node *p){ if(NULL == p->next) return;//只有头,无值时无法pop while(NULL != p->next) { printf("%d,",p->num_ch); p = p->next; } putchar(10);}/*** 计算int变量的长度** 例如1234长度为4*/int sum_int(int in){ int len=0; while(0 != in) { len++; in /= 10; } return len;}/*** 符号优先级判断** 返回: 1(opt1>opt2) -1(opt1<opt2) 0(opt1=opt2)** 注意符号的ASSIC码:43(+) 45(-) 42(*) 47(/)*/int opt_max(int opt1,int opt2){ if(42 == opt1 || 47 == opt1) { if(43 == opt2 || 45 == opt2) { return 1; } return 0; } else { if(42 == opt2 || 47 == opt2) { return -1; } return 0; }}/*** 计算a和b在mode符号的运算结果*/int cal(int a,int b,int mode){ int re = -1; switch(mode) { case 43:re = a + b;break; case 45:re = a - b;break; case 42:re = a * b;break; case 47:re = a / b;break; default: break; } return re;}/*** 计算表达式的值** 核心关键*/int cal_str(char *str){int num1,num2,opt1,opt2;node *num,*opt;num = CreatNode(); //创建数字栈opt = CreatNode(); //创建符号栈while( 1 ) {if('\0' == *str) {// 读到字符串末尾 /* ** 如果最后一个符号是*或/则会剩下三个数字和两个符号 ** 如果最后一个符号时+或-则会剩下两个数字和一个符号 ** 结果只是算两次和算一次的问题 */ opt1 = gettop(opt); if((42 == opt1) || (47 == opt1)) { num2 = pop(num); num1 = pop(num); opt2 = pop(opt); push(num, cal(num1, num2, opt2)); } num2 = pop(num); num1 = pop(num); opt2 = pop(opt); num1 = cal(num1, num2, opt2); break;} else if('(' == *str) {// 读到(,注意压栈的时(的ASSIC码40 push(opt, (int)'('); str++;} else if(')' == *str) {// 只是判断)不压入栈 while( 1 ) {// 本循环会计算与)匹配的最近的(地方为之 if(40 == gettop(opt)) {// 如果当前栈顶是(则弾栈退出 pop(opt); break; } else {// 否则弾两个数字,一个符号进行运算 // 结果入操作数栈 num2 = pop(num); num1 = pop(num); opt2 = pop(opt); push(num, cal(num1, num2, opt2)); } } str++;} else if(('9' >= *str) && ('0' <= *str)) {// 如果取到数字则将数字压入栈 sscanf(str, "%d", &num1); push(num, num1); //将指针移动到当前数字到后面 str = str + sum_int(num1);} else {// 取到一个符号 opt1 = (int)*str++; while(1) { if( (1 == isEmpty(opt)) || (40 == gettop(opt)) ) {// 如果栈不空则遇到(则压入取到的符号 // 为空时也要压栈 push(opt, opt1); break; } else { //取出符号栈顶元素 opt2 = gettop(opt); if(0 < opt_max(opt1,opt2)) {// 当前获取的符号优先级大于栈顶符号 // 则压栈 push(opt,opt1); break; } else {// 栈顶优先级高或者平级则 // 取两个数和栈顶符号进行运算 num2 = pop(num); num1 = pop(num); opt2 = pop(opt); push(num, cal(num1, num2, opt2)); } } }} } free(num); free(opt); return num1;}int main(int argc,char **argv){char buf[N] = {0};scanf("%s", buf); getchar(); printf("%s=%d\n",buf,cal_str(buf));return 0;}
至于原理嘛栈的操作我就不多叙述了。主要讲讲算法的事情,首先计算函数感开始的时候就创建了数字栈和符号栈。处理的时候把所有字符串里取出来的东西都在栈里用整形保存,这样可以统一数字栈和符号栈是同种结构。当遍历字符串时遇到数字字符就把当前开始的数字取出来压数字栈,当遇到左括号是总是压符号栈不管连续多少个左括号,当遇到右括号时就从数字栈和符号栈中取值计算并从新压栈,直到遇到左括号,期间还要比较运算符的优先级等。当遇到字符串结束时还没有计算完成,此时数字栈和字符栈内都有值。如果符号栈内是*、/那么要计算两次,如果是+、-则计算一次。最终得出结果。我写这个程序时思路还是清晰的,就是不知道有没有小问题,希望能给大家一些启发。测试出问题也希望大家给我说,大家一起进步嘛。
0 0
- C语言实现表达式求值,支持+、-、*、/四则运算,并且支持多级括号,自定义了栈的操作。
- 栈的测试--四则运算表达式求值(C语言)
- 逆波兰式实现四则运算表达式计算器支持括号、十六进制
- 栈的操作和c语言实现算术表达式求值
- 带括号的四则运算C语言实现
- 支持多位数,括号,四则运算,的计算器算法c++实现
- Linux系统下用C语言实现浮点数四则运算表达式的求值
- c语言:表达式求值实现(包含加减乘除括号)
- 栈的应用--四则运算表达式求值(java语言)
- 支持用户自定义变量的PowerBuilder表达式求值
- 四则运算表达式树 C++模板 支持括号和未知数
- 数据结构之简单四则运算表达式求值8-(栈的实现)
- 计算表达式的值(仅含有四则运算和支持括号嵌套,浮点数运算)
- 表达式求值(C实现,实现多括号,浮点数)---栈的实现以及运用。
- stl表达式求值(支持括号空格版)
- c语言栈实现表达式求值
- 栈实现表达式求值(C语言)
- 栈实现表达式求值(C语言)
- Visual Basic 2.0推出没几个月
- VB 的组件既可以拥有用户界面
- 【This VI】LabVIEW Match 1D String Array.vi
- Java远程连接操作linux服务器,scp获取文件
- Mac 10.10下的sandBox目录
- C语言实现表达式求值,支持+、-、*、/四则运算,并且支持多级括号,自定义了栈的操作。
- 无栈非递归中序遍历非线索化二叉树
- 无人值守安装
- lua教程
- Linux 下挂载硬盘的 方法
- 前端自动化流程
- 嵌入式CGI开发之旅——CGI环境变量
- 用户界面View之DatePicker与TimePicker
- sgu101