用c语言做一个栈,完成逆波兰表达式
2018-03-12 15:30
218 查看
先用c语言,实现了一个栈结构,在用栈完成逆波兰表达式。 包含中缀表达式 -》 后缀表达式, 用栈完成计算。#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
double data;
struct Stack * next;
} Node;
typedef struct Stack
{
Node * data;
int count;
} Stack;
Stack * s ;
// 生成栈
void initStack()
{
s = (Stack *)malloc(sizeof(Stack));
s->count = 0;
s->data = NULL;
}
// 入栈,push
void push(double data)
{
printf("%f 即将被入栈\n",data);
Node * n = malloc(sizeof(Node));
n->data = data;
n->next = s->data;
s->data = n;
s->count ++;
}
// 出栈,pop
double pop()
{
if(s->data == NULL)
{
printf("已经是空栈了\n");
return;
}
Node * n = s->data;
double r = n->data;
printf("数据 %f 即将出栈\n",n->data);
s->data=n->next;
free(n);
s->count--;
return r;
}
// 清空栈
void clearStack()
{
while (s->data != NULL)
{
pop();
}
}
// 获取栈顶元素
double topItem()
{
if (s->data==NULL)
{
printf("此栈为空栈\n");
return;
}
printf("此栈中元素数量为 %d 个,栈顶为 %f\n",s->count,s->data->data);
return s->data->data;
}
// 把字符串转成double,没有做错误检测,比如用户输入 12.35.5 5abc.64,就会出错。
double charToDouble(char * num)
{
double a = 0.0;
// 把一个字符串转成浮点型数字,记录小数点后的位数,忽略小数点转成整数,
// 然后用这个整数 除以小数点后的位数,即可得到浮点数
int havePoint = 0; //这个数中是否有小数点
int j=0; // 记录小数点后面有几位的
for(int i=0; num[i]!='\0'; i++)
{
if(num[i]=='.')
{
havePoint = 1;
continue;
}
if(havePoint==1)
{
j++;
}
a = a * 10 + num[i] - '0';
}
while(j>0)
{
a = a/10;
j--;
}
printf("字符串%s 转成 浮点数 %f\n",num,a);
return a;
}
int main()
{
initStack();
// char * str = "90*2+(3-1)*3+10/2";
char str[100] ;
printf("输入一串表达式\n");
// 键盘要换成英文输入,不然无法输入。哭...
gets(str);
// 记录逆波兰表达式的结果,
// 结构是 【0或1】 【对应值】,由于加减乘除 都是char类型,char -> int -> double,所以用double存储。
// 0 表示是数字类型, 1 表示后面的是符号类型
double niBoLan[100]={0.0};
int niI = 0; // 逆波兰表达式的下标
char num[100] = "\0"; // 把字符串导出数字使用,
int j = 0;//记录这个数字char的长度,比如 12.3 就会记录为4
for(int i=0; str[i]!='\0'; )
{
// 区分出是数字还是符号
if ((str[i]<='9'&&str[i]>='0') || str[i]=='.')
{
// 把数字转换出来
while ((str[i]<='9'&&str[i]>='0') || str[i]=='.')
{
char a = str[i];
num[j]=a;
j++;
num[j]='\0';
i++;
}
double b = charToDouble(num);
num[100] ="\0";
j=0;
niBoLan[niI] = 0;
niI ++;
niBoLan[niI] = b;
niI ++;
} else {
char a = str[i];
switch (a) {
case '+':
case '-':
while(topItem()=='*'||topItem()=='/'){
niBoLan[niI] = 1;
niI ++;
niBoLan[niI] = pop();
niI++;
}
push(a);
break;
case '*':
case '/':
case '(':
push(a);
break;
case ')':
while(topItem()!='('){
niBoLan[niI] = 1;
niI ++;
niBoLan[niI] = pop();
niI++;
}
pop(); // 需要把 ( 弹出
break;
}
i++;
}
}
// 栈中剩余的符号弹出
while (s->data != NULL)
{
niBoLan[niI] = 1;
niI ++;
niBoLan[niI] = pop();
niI++;
}
for(int i = 0;i<niI;i++) {
printf("%f ",niBoLan[i]);
}
printf("\n逆波兰转换完毕,检查一下\n");
clearStack();
printf("\n清空栈结构,开始计算结果\n");
double num1;
double num2;
for(int i = 0;i<niI;i+=2) {
// 判断标志位, 0 是数字, 1 是符号。
int isChar = niBoLan[i];
if(isChar == 0 ) {
// 数字直接入栈
push(niBoLan[i+1]);
} else {
char a = niBoLan[i+1];
switch (a) {
case '+':
push( pop() + pop() );
break;
case '-':
num1 = pop();
num2 = pop();
push( num2 - num1 );
break;
case '*':
push( pop() * pop() );
break;
case '/':
num1 = pop();
num2 = pop();
push( num2 / num1 );
break;
}
}
}
printf("\n计算结果 %f\n",pop());
}
/*
*/
#include <stdlib.h>
typedef struct Node
{
double data;
struct Stack * next;
} Node;
typedef struct Stack
{
Node * data;
int count;
} Stack;
Stack * s ;
// 生成栈
void initStack()
{
s = (Stack *)malloc(sizeof(Stack));
s->count = 0;
s->data = NULL;
}
// 入栈,push
void push(double data)
{
printf("%f 即将被入栈\n",data);
Node * n = malloc(sizeof(Node));
n->data = data;
n->next = s->data;
s->data = n;
s->count ++;
}
// 出栈,pop
double pop()
{
if(s->data == NULL)
{
printf("已经是空栈了\n");
return;
}
Node * n = s->data;
double r = n->data;
printf("数据 %f 即将出栈\n",n->data);
s->data=n->next;
free(n);
s->count--;
return r;
}
// 清空栈
void clearStack()
{
while (s->data != NULL)
{
pop();
}
}
// 获取栈顶元素
double topItem()
{
if (s->data==NULL)
{
printf("此栈为空栈\n");
return;
}
printf("此栈中元素数量为 %d 个,栈顶为 %f\n",s->count,s->data->data);
return s->data->data;
}
// 把字符串转成double,没有做错误检测,比如用户输入 12.35.5 5abc.64,就会出错。
double charToDouble(char * num)
{
double a = 0.0;
// 把一个字符串转成浮点型数字,记录小数点后的位数,忽略小数点转成整数,
// 然后用这个整数 除以小数点后的位数,即可得到浮点数
int havePoint = 0; //这个数中是否有小数点
int j=0; // 记录小数点后面有几位的
for(int i=0; num[i]!='\0'; i++)
{
if(num[i]=='.')
{
havePoint = 1;
continue;
}
if(havePoint==1)
{
j++;
}
a = a * 10 + num[i] - '0';
}
while(j>0)
{
a = a/10;
j--;
}
printf("字符串%s 转成 浮点数 %f\n",num,a);
return a;
}
int main()
{
initStack();
// char * str = "90*2+(3-1)*3+10/2";
char str[100] ;
printf("输入一串表达式\n");
// 键盘要换成英文输入,不然无法输入。哭...
gets(str);
// 记录逆波兰表达式的结果,
// 结构是 【0或1】 【对应值】,由于加减乘除 都是char类型,char -> int -> double,所以用double存储。
// 0 表示是数字类型, 1 表示后面的是符号类型
double niBoLan[100]={0.0};
int niI = 0; // 逆波兰表达式的下标
char num[100] = "\0"; // 把字符串导出数字使用,
int j = 0;//记录这个数字char的长度,比如 12.3 就会记录为4
for(int i=0; str[i]!='\0'; )
{
// 区分出是数字还是符号
if ((str[i]<='9'&&str[i]>='0') || str[i]=='.')
{
// 把数字转换出来
while ((str[i]<='9'&&str[i]>='0') || str[i]=='.')
{
char a = str[i];
num[j]=a;
j++;
num[j]='\0';
i++;
}
double b = charToDouble(num);
num[100] ="\0";
j=0;
niBoLan[niI] = 0;
niI ++;
niBoLan[niI] = b;
niI ++;
} else {
char a = str[i];
switch (a) {
case '+':
case '-':
while(topItem()=='*'||topItem()=='/'){
niBoLan[niI] = 1;
niI ++;
niBoLan[niI] = pop();
niI++;
}
push(a);
break;
case '*':
case '/':
case '(':
push(a);
break;
case ')':
while(topItem()!='('){
niBoLan[niI] = 1;
niI ++;
niBoLan[niI] = pop();
niI++;
}
pop(); // 需要把 ( 弹出
break;
}
i++;
}
}
// 栈中剩余的符号弹出
while (s->data != NULL)
{
niBoLan[niI] = 1;
niI ++;
niBoLan[niI] = pop();
niI++;
}
for(int i = 0;i<niI;i++) {
printf("%f ",niBoLan[i]);
}
printf("\n逆波兰转换完毕,检查一下\n");
clearStack();
printf("\n清空栈结构,开始计算结果\n");
double num1;
double num2;
for(int i = 0;i<niI;i+=2) {
// 判断标志位, 0 是数字, 1 是符号。
int isChar = niBoLan[i];
if(isChar == 0 ) {
// 数字直接入栈
push(niBoLan[i+1]);
} else {
char a = niBoLan[i+1];
switch (a) {
case '+':
push( pop() + pop() );
break;
case '-':
num1 = pop();
num2 = pop();
push( num2 - num1 );
break;
case '*':
push( pop() * pop() );
break;
case '/':
num1 = pop();
num2 = pop();
push( num2 / num1 );
break;
}
}
}
printf("\n计算结果 %f\n",pop());
}
/*
*/
相关文章推荐
- 第四天学习数据结构,完成一半的逆波兰表达式
- 逆波兰表达式——第四届蓝桥杯省赛C语言A组第6题
- 应用Notepad++的正则表达式完成较复杂替换的一个小例子
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- C语言一个语句完成浮点数四舍五入
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- 一个逆波兰表达式实现的四则混合运算计算器
- 开始学习python了,第一个程序是一个逆波兰式的表达式分析器
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- 使用c语言完成了一个求素数的程序
- 【晨哥的C语言之旅】逆波兰表达式实现计算器功能
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- 从键盘上输入一个后缀表达式,试编写算法计算表达式的值。规定:逆波兰表达式的长度不超过一行,以$符作为输入结束,操作数之间用空格分隔,操作符只可能有+、-、*、/四种运算。例如:234 34+2*$。
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- C语言下的创建一个数组, 实现函数init()初始化数组、 实现empty()清空数组、 实现reverse()函数完成数组元素的逆置。 要求:自己设计函数的参数,返回值。
- C语言数据结构之逆波兰表达式求值
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- C语言简单计算器原理——表达式求值(采用逆波兰表达式和栈结合)
- C语言为什么被const声明的变量不是一个常量表达式