一步一步解决表达式计算问题
来源:互联网 发布:姚记密码扑克牌淘宝 编辑:程序博客网 时间:2024/06/10 19:25
//链式栈的实际应用-----表达式计算
思考:如果我想要用栈实现下列公式的计算,该怎么办?
(注:这里先不考虑空格问题)
//1+123*5;
char buf[1024];
思考:"123"如何转换成整型数123?
答案:
int data = 0;
for(i = 0;i < 3;i++){
data = data * 10 + buf[i] - '\0';
}
思路:
1、创建两个栈
linkstack * operand ;//运算数栈
linkstack * operator; //运算符栈
2、扫描表达式。
<1>若是运算数,合并成一个完整的数data。
规则:直接入操作数栈
push_stack(operator_stack,data);
<2>若是操作符(考虑优先级问题)
规则:1、栈为空,直接入栈
2、当前的运算符号优先级 == 栈顶符合的优先级
直接从运算数栈中取出两个数,再取出栈顶符号。
把计算的结果入运算数栈,然后再把当前的运算符
入符号栈。
(例如:1 + 2 + 4 - 2中,1和2入数据栈,+入符号
栈,比较+和-优先级一样,则计算1+2= 3.
然后结果3入栈,4入栈,+入栈。再次计算)
3、当前的运算符号优先级 >栈顶符合的优先级
不要计算,把当前符号直接再次入栈,此时栈顶元素为
当前符号,然后再把数据入栈,当新的符号来的时候,
比较符号和栈顶元素,若是小于栈顶元素的话,则计算。
(例如:1 + 2 * 3-4,1和2入栈,+入栈,然后判断*和+的
优先级,* > + ,*入栈,3 入栈, 然后判断-和*
的优先级,则- < *,则计算2 和3出栈,*出栈,计算
2 * 3 = 6,然后6入栈,在计算+ 和 -的优先级,一样
则,计算1 + 6 = 7,然后7入栈,4入栈,-入栈,依次计算)
提示:
1、获得优先级函数
int get_level(char operator)
{
switch(operator)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
defalut:
printf("Invalid operator : %c.\n",operator);
return -1;
}
}
2、计算+、-、*、/函数
//参数说明:
//opd 运算数
//opt 运算符
int compute(linkstack *opd,linkstack *opt)
{
int data,data1,data2;
char c = 0;
data2 = pop_stack(opd); //运算数2出栈
data1 = pop_stack(opd);//运算数1出栈
c = pop_stack(opt); //运算符出栈
switch(c)
{
case '+':
data = data1 + data2;
break;
......
}
push_satck(data,opd);//把最后获得的运算数入栈。
}
3、得到最终结果的条件:
当扫描结果的时候,判断运算符栈是否为空,
若是为空则计算,若是不为空,则为空,则
操作数栈中的结果,为我们最后的结果。
4、主函数框架
char buf[1024];
char *p = buf;
int data = 0; //运算数
//输入数据到buf中
while(*p != '\0')
{
//获得运算数
if(*p >= '0' && *p <= '9')
{
data = 0;
//获得运算数
//入运算数栈
continue;
}
if(*p == '+' || *p == '-' .....)
{
//处理运算符
deal_with(operand,operator,*p);
p++;
continue;
}
}
//最后遍历玩表达式,输出运算数栈中的结果,就是我们最终的数据。
//若是用到我们的括号,我们就需要更新代码。
如下图所示:
代码详解:
head.h
#ifndef _HEAD_H_#define _HEAD_H_#include <stdio.h>#include <stdlib.h>#include <string.h>#define N 100//数据元素的类型typedef int data_t;//链表的结点类型typedef struct node{ data_t data; struct node *next;}linknode_t;//栈头类型typedef struct{ //栈顶指针 linknode_t *top; //栈中元素个数 int n;}linkstack_t;extern linkstack_t *create_empty_linkstack();extern int is_empty_linkstack(linkstack_t *s);extern int push_linkstack(linkstack_t *s,data_t data);extern data_t pop_linkstack(linkstack_t *s);extern data_t get_top_data(linkstack_t *s);#endif
linkstack.c
#include "head.h"linkstack_t *create_empty_linkstack(){ linkstack_t *s = NULL; s = (linkstack_t *)malloc(sizeof(linkstack_t)); s->top = NULL; s->n = 0; return s;}int is_empty_linkstack(linkstack_t *s){ return s->top == NULL;}int push_linkstack(linkstack_t *s,data_t data){ linknode_t *temp = NULL; temp = (linknode_t *)malloc(sizeof(linknode_t)); temp->data = data; temp->next = s->top; s->top = temp; s->n++; return 0;}data_t pop_linkstack(linkstack_t *s){ linknode_t *temp = NULL; data_t data; temp = s->top; data = temp->data; s->top = temp->next; free(temp); temp = NULL; s->n--; return data;}data_t get_top_data(linkstack_t *s){ return s->top->data;}#if 0int main(){ linkstack_t *s = NULL; int i = 0; s = create_empty_linkstack(); for(i = 0;i < 10;i++) { push_linkstack(s,i); } printf("Top data : %d\n",get_top_data(s)); while(!is_empty_linkstack(s)) { printf("%-5d",pop_linkstack(s)); } putchar('\n'); return 0;}#endif
expression.c
#include "head.h"int get_priority(char c){ switch(c) { case '(': return 0; case '+': case '-': return 1; case '*': case '/': return 2; } return -1;}int compute(linkstack_t *operand,linkstack_t *operator){ int data = 0,data1 = 0,data2 = 0; data2 = pop_linkstack(operand); data1 = pop_linkstack(operand); switch(pop_linkstack(operator)) { case '+': data = data1 + data2; break; case '-': data = data1 - data2; break; case '*': data = data1 * data2; break; case '/': data = data1 / data2; break; } push_linkstack(operand,data); return 0;}int deal_with(linkstack_t *operand,linkstack_t *operator,char c){ int cur_level = 0; cur_level = get_priority(c);#if 0 int top_level = 0; while(1) { if(is_empty_linkstack(operator)) { push_linkstack(operator,c); return 0; } top_level = get_priority(get_top_data(operator)); if(cur_level > top_level) { push_linkstack(operator,c); return 0; } compute(operand,operator); }#else /*while(!(is_empty_linkstack(operator) || cur_level > get_priority(get_top_data(operator))))*/ while(1) { if(is_empty_linkstack(operator) || cur_level > get_priority(get_top_data(operator))) { push_linkstack(operator,c); return 0; } compute(operand,operator); }#endif return 0;}int compute_expression(char *p,int *pres){ int data = 0; linkstack_t *operand = NULL;//运算数栈 linkstack_t *operator = NULL;//运算符栈 operand = create_empty_linkstack(); operator = create_empty_linkstack(); /*while(*p != '\0')*/ while(*p) { if(*p == ' ') { p++; continue; }#if 0 if(*p >= '0' && *p <= '9') { push_linkstack(operand,*p - '0'); p++; continue; }#endif if(*p >= '0' && *p <= '9') { data = 0; while(*p >= '0' && *p <= '9') { data = data * 10 + *p - '0'; p++; } // printf("data = %d\n",data); push_linkstack(operand,data); continue; } if(*p == '+' || *p == '-' || *p == '*' || *p == '/') { deal_with(operand,operator,*p); p++; continue; } if(*p == '(') { push_linkstack(operator,*p); p++; continue; } if(*p == ')') { while(!is_empty_linkstack(operator) && get_top_data(operator) != '(') { compute(operand,operator); } if(is_empty_linkstack(operator)) { /*printf("'(' lost\n");*/ return -2; } pop_linkstack(operator); p++; continue; } //printf("Invalid char %c\n",*p); return -1; } while(!is_empty_linkstack(operator)) { compute(operand,operator); } *pres = pop_linkstack(operand); return 0;}int main(){ char buf[N] = {0}; int result = 0; int ret = 0; printf("Input expression: "); scanf("%99[^\n]",buf); /*puts(buf);*/ if((ret = compute_expression(buf,&result)) < 0) { if(ret == -1) { printf("Invalid char\n"); } else if(ret == -2) { printf("( lost\n"); } return -1; } printf("%s = %d\n",buf,result); return 0;}
运行结果:
- 一步一步解决表达式计算问题
- 表达式计算的问题
- 一步一步解决Ajax传值问题
- 一步一步解决一个机器学习问题
- 解决excel计算问题
- 关于表达式计算的问题
- c++实现表达式计算问题
- 一步一步全面解决mysql+jsp的中文问题
- Java解决高精度计算问题
- 解决一个正则表达式问题
- 在C#中解决动态计算表达式的问题(如字符串"Sin(1)+Cos(2)",执行并得出结果)
- 逆波兰表达式的计算问题
- Java 数据结构和算法 计算表达式问题
- C++实现 逆波兰表达式计算问题
- 解决opengl计算顶点法向量问题
- 解决opengl计算顶点法向量问题
- js金额计算解决精度问题
- 解决opengl计算顶点法向量问题
- fusion char asp.net
- gdb使用方法
- HTML 5调用摄像头并进行拍照
- python:numpy的一些命令
- cinder error_deleting
- 一步一步解决表达式计算问题
- Android之四大组件之一-Activity(六)扩展
- java虚拟机之内存区域与内存溢出异常
- 可以根随Cell移动的标志
- float的使用问题和c的一些运算问题
- POJ - 3468 A Simple Problem with Integers
- jmeter的http cookies管理器使用
- python数据类型转换(二(5))
- 身份证合成编辑