四则运算表达式的值
2013-05-27 21:28
148 查看
转载一篇文章,处理四则运算表达式的值,增加了部分我的注释
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int MAXSIZE = 100;
//栈的数据结构
typedef struct
{
int data[MAXSIZE];
int top;
} Stack; //既然使用栈结构,对于入栈,出栈操作,如果用封装的函数,就更加明了。
/*
void initStack(Stack *sta)
{
for(int i=0; i<MAXSIZE; i++)
{
sta->data[i]=0;
}
sta->top=-1;
}
void push(Stack *sta,int elem)
{
sta->top++;
sta->data[sta->top]=elem;
}
int pop(Stack *sta)
{
int elem;
elem=sta->data[sta->top];
sta->top--;
return elem;
}
*/
int table[] = {0,0,2,1,0,1,0,2}; //自定义运算符优先级表,根据ASCII码的模,作为数组下标,此中方法也常用到,很妙
// ' * ' 42
// ' + ' 43
// ' - ' 45
// ' / ' 47
//函数说明:将中缀表达式转换为后缀表达式
//参数说明:
//sta: 转换过程需使用的栈空间
//infix: 待转换的中缀表达式
//suffix: 存储转换后的后缀表达式
//length: 记录后缀表达式的长度
void infix_to_suffix(Stack *sta, char *infix, int *suffix, int *length); //之前一直就迷茫,如何把输入的字符串,转换成数字和字符,后来也想到全用int数组。字符用ASCII码也可表示为int
//函数说明:将后缀表达式转换为结果直接返回
//参数说明:
//sta: 转换过程需使用的栈空间
//suffix: 存储转换后的后缀表达式
//length: 记录后缀表达式的长度
int suffix_to_result(Stack *sta, int *suffix, int length);
void init(Stack *sta);//栈空间初始化
int main()
{
//这里将标准输入输出流重定向到文件中
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
Stack sta;
int length;
int result; //接受后缀表达式转换的结果
int sstr[MAXSIZE]; //存储后缀表达式
char istr[MAXSIZE]; //存储中缀表达式
printf("请输入以 + - * / 组成的四则运算\n(注意负数需要在两旁添加上括号)\n");
scanf("%s", istr);
init(&sta); //对栈空间初始化
infix_to_suffix(&sta, istr, sstr, &length);
init(&sta); //再次对栈空间初始化
result = suffix_to_result(&sta, sstr, length);
printf("%d\n", result);
// fclose(stdin);
// fclose(stdout);
return 0;
}
void infix_to_suffix(Stack *sta, char *infix, int *suffix, int *length)
{
int i; //循环变量
int b = 0; //当数字是十位或以上的时候进行记录
int j = 0; //suffix数组的下标
int priority = 0; //记录栈顶元素的优先级
//for循环的第三表达式不进行i++,将其放在每一次的压栈后或直接输出到suffix进行i++
for (i = 0; i < strlen(infix); )
{
//如果是数字的话,直接放在suffix中,然后continue,对数字的处理,因为输入的是当做一个一个的字符存储的,所以,要还原为数字,需要借助ASCII的差值48('0’),进行转换。
if (infix[i] >= '0' && infix[i] <= '9')
{
b = 0; //谨记每次都需重新赋值为零!
while (infix[i] >= '0' && infix[i] <= '9')
{
b = b * 10 + (infix[i] - '0');
i++;
}
suffix[j] = b;
j++;
continue;
}
//如果是右括号的话,将栈中在左括号以上的所有运算符弹出,然后continue
if (infix[i] == 41)
{
while (sta->data[sta->top] != 40)
{
suffix[j] = sta->data[sta->top];
sta->data[sta->top] = 0;
sta->top--;
j++;
}
sta->data[sta->top] = 0;
sta->top--;
//注意出栈后,须将新的栈顶元素的优先级记录下来
priority = table[sta->data[sta->top] % 10];
i++;
continue;
}
//如果是左括号的话,直接压栈
if (infix[i] == 40)
{
sta->top++;
sta->data[sta->top] = infix[i];
//注意压栈后,须将新的栈顶元素的优先级记录下来
priority = table[sta->data[sta->top] % 10];
i++;
continue;
}
//如果只是普通的运算符,则压栈
if (infix[i] >= 42 && infix[i] <= 47)
{
//首先比较栈顶元素的优先级是否比入栈元素优先级要大
//如果是大于的话,则从栈顶将元素依次出栈后,把待入栈的元素压栈
if (priority >= table[infix[i] % 10])
{
while (priority >= table[infix[i] % 10] && sta->data[sta->top] != 40)
{
suffix[j] = sta->data[sta->top];
sta->data[sta->top] = 0;
sta->top--;
//注意每次的出栈后,须将新的栈顶元素的优先级记录下来用作比较
priority = table[sta->data[sta->top] % 10];
j++;
}
sta->top++;
sta->data[sta->top] = infix[i];
//注意压栈后,须将新的栈顶元素的优先级记录下来
priority = table[sta->data[sta->top] % 10];
i++;
}
else
{
//这里主要处理负数的提取
if (infix[i] == 45 && sta->data[sta->top] == 40)
{
b = 0;
while (infix[i+1] >= '0' && infix[i+1] <= '9')
{
b = b * 10 + (infix[i+1] - '0');
i++;
}
suffix[j] = b * -1;
sta->data[sta->top] = 0;
sta->top--;
j++;
i += 2;
priority = table[sta->data[sta->top] % 10];
continue;
}
sta->top++;
sta->data[sta->top] = infix[i];
//注意压栈后,须将新的栈顶元素的优先级记录下来
priority = table[sta->data[sta->top] % 10];
i++;
}
}
}
//把栈中还存在的元素进行弹出
while (sta->top != -1)
{
suffix[j] = sta->data[sta->top];
sta->top--;
j++;
}
*length = j;
}
int suffix_to_result(Stack *sta, int *suffix, int length)
{
int i;
int j;
int result = 0;
for (i = 0; i < length; i++)
{
//循环遍历后缀表达式,数字就直接压栈,运算符就取栈顶两个元素出来计算,并将结果压栈
switch (suffix[i])
{
case 42:
result = sta->data[sta->top - 1] * sta->data[sta->top];
sta->top -= 1;
sta->data[sta->top] = result;
break;
case 43:
result = sta->data[sta->top - 1] + sta->data[sta->top];
sta->top -= 1;
sta->data[sta->top] = result;
break;
case 45:
result = sta->data[sta->top - 1] - sta->data[sta->top];
sta->top -= 1;
sta->data[sta->top] = result;
break;
case 47:
result = sta->data[sta->top - 1] / sta->data[sta->top];
sta->top -= 1;
sta->data[sta->top] = result;
break;
default:
sta->top++;
sta->data[sta->top] = suffix[i];
break;
}
}
return result;
}
//初始化栈空间
void init(Stack *sta)
{
int i;
for (i = 0; i < MAXSIZE; i++)
{
sta->data[i] = 0;
}
sta->top = -1;
}
文章转自:http://blog.csdn.net/cbs612537/article/details/8274512
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int MAXSIZE = 100;
//栈的数据结构
typedef struct
{
int data[MAXSIZE];
int top;
} Stack; //既然使用栈结构,对于入栈,出栈操作,如果用封装的函数,就更加明了。
/*
void initStack(Stack *sta)
{
for(int i=0; i<MAXSIZE; i++)
{
sta->data[i]=0;
}
sta->top=-1;
}
void push(Stack *sta,int elem)
{
sta->top++;
sta->data[sta->top]=elem;
}
int pop(Stack *sta)
{
int elem;
elem=sta->data[sta->top];
sta->top--;
return elem;
}
*/
int table[] = {0,0,2,1,0,1,0,2}; //自定义运算符优先级表,根据ASCII码的模,作为数组下标,此中方法也常用到,很妙
// ' * ' 42
// ' + ' 43
// ' - ' 45
// ' / ' 47
//函数说明:将中缀表达式转换为后缀表达式
//参数说明:
//sta: 转换过程需使用的栈空间
//infix: 待转换的中缀表达式
//suffix: 存储转换后的后缀表达式
//length: 记录后缀表达式的长度
void infix_to_suffix(Stack *sta, char *infix, int *suffix, int *length); //之前一直就迷茫,如何把输入的字符串,转换成数字和字符,后来也想到全用int数组。字符用ASCII码也可表示为int
//函数说明:将后缀表达式转换为结果直接返回
//参数说明:
//sta: 转换过程需使用的栈空间
//suffix: 存储转换后的后缀表达式
//length: 记录后缀表达式的长度
int suffix_to_result(Stack *sta, int *suffix, int length);
void init(Stack *sta);//栈空间初始化
int main()
{
//这里将标准输入输出流重定向到文件中
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
Stack sta;
int length;
int result; //接受后缀表达式转换的结果
int sstr[MAXSIZE]; //存储后缀表达式
char istr[MAXSIZE]; //存储中缀表达式
printf("请输入以 + - * / 组成的四则运算\n(注意负数需要在两旁添加上括号)\n");
scanf("%s", istr);
init(&sta); //对栈空间初始化
infix_to_suffix(&sta, istr, sstr, &length);
init(&sta); //再次对栈空间初始化
result = suffix_to_result(&sta, sstr, length);
printf("%d\n", result);
// fclose(stdin);
// fclose(stdout);
return 0;
}
void infix_to_suffix(Stack *sta, char *infix, int *suffix, int *length)
{
int i; //循环变量
int b = 0; //当数字是十位或以上的时候进行记录
int j = 0; //suffix数组的下标
int priority = 0; //记录栈顶元素的优先级
//for循环的第三表达式不进行i++,将其放在每一次的压栈后或直接输出到suffix进行i++
for (i = 0; i < strlen(infix); )
{
//如果是数字的话,直接放在suffix中,然后continue,对数字的处理,因为输入的是当做一个一个的字符存储的,所以,要还原为数字,需要借助ASCII的差值48('0’),进行转换。
if (infix[i] >= '0' && infix[i] <= '9')
{
b = 0; //谨记每次都需重新赋值为零!
while (infix[i] >= '0' && infix[i] <= '9')
{
b = b * 10 + (infix[i] - '0');
i++;
}
suffix[j] = b;
j++;
continue;
}
//如果是右括号的话,将栈中在左括号以上的所有运算符弹出,然后continue
if (infix[i] == 41)
{
while (sta->data[sta->top] != 40)
{
suffix[j] = sta->data[sta->top];
sta->data[sta->top] = 0;
sta->top--;
j++;
}
sta->data[sta->top] = 0;
sta->top--;
//注意出栈后,须将新的栈顶元素的优先级记录下来
priority = table[sta->data[sta->top] % 10];
i++;
continue;
}
//如果是左括号的话,直接压栈
if (infix[i] == 40)
{
sta->top++;
sta->data[sta->top] = infix[i];
//注意压栈后,须将新的栈顶元素的优先级记录下来
priority = table[sta->data[sta->top] % 10];
i++;
continue;
}
//如果只是普通的运算符,则压栈
if (infix[i] >= 42 && infix[i] <= 47)
{
//首先比较栈顶元素的优先级是否比入栈元素优先级要大
//如果是大于的话,则从栈顶将元素依次出栈后,把待入栈的元素压栈
if (priority >= table[infix[i] % 10])
{
while (priority >= table[infix[i] % 10] && sta->data[sta->top] != 40)
{
suffix[j] = sta->data[sta->top];
sta->data[sta->top] = 0;
sta->top--;
//注意每次的出栈后,须将新的栈顶元素的优先级记录下来用作比较
priority = table[sta->data[sta->top] % 10];
j++;
}
sta->top++;
sta->data[sta->top] = infix[i];
//注意压栈后,须将新的栈顶元素的优先级记录下来
priority = table[sta->data[sta->top] % 10];
i++;
}
else
{
//这里主要处理负数的提取
if (infix[i] == 45 && sta->data[sta->top] == 40)
{
b = 0;
while (infix[i+1] >= '0' && infix[i+1] <= '9')
{
b = b * 10 + (infix[i+1] - '0');
i++;
}
suffix[j] = b * -1;
sta->data[sta->top] = 0;
sta->top--;
j++;
i += 2;
priority = table[sta->data[sta->top] % 10];
continue;
}
sta->top++;
sta->data[sta->top] = infix[i];
//注意压栈后,须将新的栈顶元素的优先级记录下来
priority = table[sta->data[sta->top] % 10];
i++;
}
}
}
//把栈中还存在的元素进行弹出
while (sta->top != -1)
{
suffix[j] = sta->data[sta->top];
sta->top--;
j++;
}
*length = j;
}
int suffix_to_result(Stack *sta, int *suffix, int length)
{
int i;
int j;
int result = 0;
for (i = 0; i < length; i++)
{
//循环遍历后缀表达式,数字就直接压栈,运算符就取栈顶两个元素出来计算,并将结果压栈
switch (suffix[i])
{
case 42:
result = sta->data[sta->top - 1] * sta->data[sta->top];
sta->top -= 1;
sta->data[sta->top] = result;
break;
case 43:
result = sta->data[sta->top - 1] + sta->data[sta->top];
sta->top -= 1;
sta->data[sta->top] = result;
break;
case 45:
result = sta->data[sta->top - 1] - sta->data[sta->top];
sta->top -= 1;
sta->data[sta->top] = result;
break;
case 47:
result = sta->data[sta->top - 1] / sta->data[sta->top];
sta->top -= 1;
sta->data[sta->top] = result;
break;
default:
sta->top++;
sta->data[sta->top] = suffix[i];
break;
}
}
return result;
}
//初始化栈空间
void init(Stack *sta)
{
int i;
for (i = 0; i < MAXSIZE; i++)
{
sta->data[i] = 0;
}
sta->top = -1;
}
文章转自:http://blog.csdn.net/cbs612537/article/details/8274512
相关文章推荐
- 表达式运算,四则混合运算
- 中缀表达式的计算(只包含四则运算与括号)
- 栈的应用:四则运算表达式求值
- [数据结构与算法] 5,栈的应用-四则运算表达式求值
- 栈的应用:四则运算表达式求值
- 表达式(四则运算)计算的算法
- java 解析四则混合运算表达式并计算结果
- C++计算四则运算表达式程序
- 正则表达式实现的加减乘除四则运算的计算器
- 使用 正则表达式 验证四则运算表达式
- 四则运算表达式求值(栈的应用)
- 基于c语言的数据结构之栈应用(二)四则运算表达式的应用
- 在Java中计算四则运算表达式字符串的值
- 【个人项目总结】C#四则运算表达式生成程序
- 栈的应用-四则运算表达式求值
- hdu 3000 A Simple Language (逆波兰式计算四则运算表达式数值)
- 四则运算表达式解析和求值(支持括号、小数)
- 1024. 分析四则运算表达式
- 一个逆波兰表达式实现的四则混合运算计算器
- 四则运算表达式求值