中缀表达式求值(代码求改,最好能加上浮点)

欢欣之雨 2011-11-19 01:11:36

#include <stdio.h>
#include <malloc.h>
#include <conio.h>
typedef struct node
{
char data;
struct node *next;
}snode,*slink;


int Emptystack(slink S)
{
if(S==NULL)return 1;
else return 0;
}

char Pop(slink top)
{
char e;
slink p;
if(Emptystack(top))return -1;
else
{
e=(top)->data;
p=top;top=(top)->next;
free(p);return e;
}
}

void Push(slink top,char e)
{
slink p;
p=(slink)malloc(sizeof(snode));
p->data=e;
p->next=top;
top=p;
}

void Clearstack(slink top)
{
slink p;
while(top!=NULL)
{
p=(top)->next;
Pop(top);
top=p;
}
top=NULL;
}

char Getstop(slink S)
{
if(S!=NULL)return(S->data);
return 0;
}

int Precede(char x,char y) /*比较x是否大于y*/
{int a,b;
switch(x)
{
case '(':a=0;break;
case '+':
case '-':a=1;break;
case '*':
case '/':a=2;break;
default:printf("字符错误");
}

switch(y)
{
case '(':b=0;break;
case '+':
case '-':b=1;break;
case '*':
case '/':b=2;break;
default:printf("字符错误");
}

if(a>=b)return 1;
else return 0;
}


void mid_post(char post[],char mid[]) //中(mid)、后(post)缀表达式转换
{
int i=0,j=0;
char x;
slink S;
S = (slink)malloc(sizeof(snode));
Clearstack(S);
Push(S,'#'); //‘#’入栈
do
{
x=mid[i++] ; //扫描当前表达式分量
switch(x)
{
case '#': {while(!Emptystack(S))
post[j++]=Pop(S);
}break; //输出栈顶运算符,并退栈

case ')':
{ while(Getstop(S)!='(')
post[j++]=Pop(S); //输出栈顶
Pop(S); //退掉‘(’
}break;
case '+': //x为运算符
case '-':
case '*':
case '/':
case '(':
{ while(Precede(Getstop(S), x)) //栈顶运算符(Q1)与x比较
{
post[j++]=Pop(S); // (Q1>=x时,输出栈顶符并栈
}
Push(S,x); //(Q1)<x时x进栈
}break;
default:post[j++]=x; //操作数直接输出
}

}
while(x!='#');
post[j]='#'; //置表达式结束符
}



int postcount(char post[]) //后缀表达式求值
{
int i=0; char x;
float z,a,b;
slink S;
S = (slink)malloc(sizeof(snode));
while(post[i]!='#')
{
x=post[i];
switch(x)
{
case '+':b=Pop(S); a=Pop(S);z=a+b; Push(S,z); break;
case '-':b=Pop(S); a=Pop(S);z=a-b; Push(S,z); break;
case '*':b=Pop(S); a=Pop(S);z=a*b; Push(S,z); break;
case '/':b=Pop(S); a=Pop(S);z=a/b; Push(S,z); break;
default:x=post[i]-'0';Push(S,x); /*Push()是字符型的,压入的是数字的ASCII码的值吗?*/
}
i++;
}
if(!Emptystack(S))return(Getstop(S));
else return 0;
}

void main()
{
char mid[255]=" ",post[255];
printf("请输入要处理的中缀表达式\n");
scanf("%s",mid);
while(getchar() != '\n') //清空缓冲区
;
printf("相应的后缀表达式为\n");
mid_post(post,mid);

printf("%s\n",post);
//printf("表达式的值为:%d",postcount(post));
getch();
}


编译通过了,运行不能写
已经分配了栈空间,为什么还是提示说不能写呢?
另外我觉得这个算法不太好,不利于求浮点数,希望有个更好一点的
...全文
278 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
小笨同学 2011-11-20
  • 打赏
  • 举报
回复
我给你写了个例子,你看懂后应该对你理解你的错误有帮助。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void fun1(char *p);
void fun2(char **p);
int main(void)
{
char *p;
fun1(p);
printf("%s\n", p);
fun2(&p);
printf("%s\n", p);
free(p);
return 0;
}

void fun1(char *p)
{
p = malloc(5 *sizeof(char));
memcpy(p, "test", 5);
}
void fun2(char **p)
{
*p = malloc(5 * sizeof(char));
memcpy(*p, "test", 5);
}
小笨同学 2011-11-20
  • 打赏
  • 举报
回复
LZ指针基础不牢固,我把你的代码改了下

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct node
{
char data;
struct node *next;
}snode,*slink;


int Emptystack(slink *S)
{
if(*S == NULL)
return 1;
else
return 0;
}

char Pop(slink *top)
{
char e;
slink p;
if(Emptystack(top))
return -1;
else
{
e = (*top)->data;
p = *top;
*top = (*top)->next;
free(p);
return e;
}
}

void Push(slink *top, char e)
{
slink p;
p = (slink)malloc(sizeof(snode));
p->data = e;
p->next = *top;
*top = p;
}

void Clearstack(slink *top)
{
slink p;
while(*top != NULL)
{
p=(*top)->next;
Pop(top);
*top=p;
}
*top=NULL;
}

char Getstop(slink *S)
{
if(*S != NULL)
return((*S)->data);
return 0;
}

int Precede(char x,char y) /*比较x是否大于y*/
{
int a,b;
switch(x)
{
case '(':a=0;break;
case '+':
case '-':a=1;break;
case '*':
case '/':a=2;break;
case '#':a=-1;break;
default:printf("字符错误");
}

switch(y)
{
case '(': b=0; break;
case '+':
case '-': b=1; break;
case '*':
case '/': b=2; break;
case '#': b=-1;break;
default : printf("字符错误");
}

if (a >= b)
return 1;
else
return 0;
}


void mid_post(char post[],char mid[]) //中(mid)、后(post)缀表达式转换
{
int i=0,j=0;
char x;
slink S = NULL;
Push(&S, '#'); //‘#’入栈
do {
x = mid[i++] ; //扫描当前表达式分量
switch(x) {
case '\0': while(!Emptystack(&S))
post[j++] = Pop(&S);
break; //输出栈顶运算符,并退栈

case ')': while(Getstop(&S) != '(')
post[j++] = Pop(&S); //输出栈顶
Pop(&S); //退掉‘(’
break;
case '+': //x为运算符
case '-':
case '*':
case '/': while(Precede(Getstop(&S), x)) //栈顶运算符(Q1)与x比较
post[j++] = Pop(&S); // (Q1>=x时,输出栈顶符并栈
Push(&S,x); //(Q1)<x时x进栈
break;
case '(': Push(&S,x); break;
default: post[j++] = x; //操作数直接输出
}
} while(x != '\0');
post[j]='\0'; //置表达式结束符
}



int postcount(char post[]) //后缀表达式求值
{
int i=0; char x;
float z,a,b;
slink S;
S = (slink)malloc(sizeof(snode));
while(post[i]!='#')
{
x=post[i];
switch(x)
{
case '+':b=Pop(&S); a=Pop(&S);z=a+b; Push(&S,z); break;
case '-':b=Pop(&S); a=Pop(&S);z=a-b; Push(&S,z); break;
case '*':b=Pop(&S); a=Pop(&S);z=a*b; Push(&S,z); break;
case '/':b=Pop(&S); a=Pop(&S);z=a/b; Push(&S,z); break;
default:x=post[i]-'0';Push(&S,x); /*Push()是字符型的,压入的是数字的ASCII码的值吗?*/
}
i++;
}
if(!Emptystack(&S))
return(Getstop(&S));
else
return 0;
}
int main(void)
{
char mid[255]=" ";
char post[255];
printf("请输入要处理的中缀表达式\n");
scanf("%s",mid);
while(getchar() != '\n') //清空缓冲区
;
printf("相应的后缀表达式为\n");
mid_post(post, mid);
printf("%s\n", post);
//printf("表达式的值为:%d",postcount(post));
return 0;
}
欢欣之雨 2011-11-19
  • 打赏
  • 举报
回复
你的那个实在是有点偏了。。。我想要的是中缀表达式转换成后缀表达式的 表达式求值。。。
尘缘udbwcso 2011-11-19
  • 打赏
  • 举报
回复

//表达式求值
#include <stdio.h>
#include <malloc.h>
#include <string.h>
/*
*功能:根据运算符计算
*参数:a, b参与运算的数, ch运算符
*返回值:计算结果,操作符错误则返回0
*/
int cal(int a, char ch, int b)
{
switch(ch)
{
case '+':
return a+b;
break;
case '-':
return a-b;
break;
case '*':
return a*b;
break;
case '/':
return a/b;
break;
}
return 0;
}
/*
*功能:计算表达式的值(用数组模拟栈)
*参数:表达式字符串
*返回值:计算结果
*/
int evaluateExpression(char *str)
{
int i = 0, result, numSub = 0, operSub = 0;
int tmp, len = strlen(str);
int *operand = (int*)malloc(sizeof(int)*len);
char *operat = (char*)malloc(sizeof(char)*len);
while(str[i] != '\0')
{
switch(str[i])
{
case '+':
while(operSub > 0 && operat[operSub-1] != '(')
{
printf("%d %c %d = ", operand[numSub-2], operat[operSub-1], operand[numSub-1]);
operand[numSub-2] = cal(operand[numSub-2], operat[operSub-1], operand[numSub-1]);
printf("%d\n", operand[numSub-2]);
--numSub;
--operSub;
}
operat[operSub++] = '+';
break;
case '-':
while(operSub > 0 && operat[operSub-1] != '(')
{
printf("%d %c %d = ", operand[numSub-2], operat[operSub-1], operand[numSub-1]);
operand[numSub-2] = cal(operand[numSub-2], operat[operSub-1], operand[numSub-1]);
printf("%d\n", operand[numSub-2]);
--numSub;
--operSub;
}
operat[operSub++] = '-';
break;
case '*':
if(str[i+1] >= '0' && str[i+1] <= '9')
{
tmp = 0;
while(str[i+1] >= '0' && str[i+1] <= '9')
{
tmp = tmp * 10 + str[i+1] - '0';
++i;
}
--i;
printf("%d * %d = ", operand[numSub-1], tmp);
operand[numSub-1] = cal(operand[numSub-1], '*', tmp);
printf("%d\n", operand[numSub-1]);
++i;
}
else
operat[operSub++] = '*';
break;
case '/':
if(str[i+1] >= '0' && str[i+1] <= '9')
{
tmp = 0;
while(str[i+1] >= '0' && str[i+1] <= '9')
{
tmp = tmp * 10 + str[i+1] - '0';
++i;
}
--i;
printf("%d / %d = ", operand[numSub-1], tmp);
operand[numSub-1] = cal(operand[numSub-1], '/', tmp);
printf("%d\n", operand[numSub-1]);
++i;
}
else
operat[operSub++] = '/';
break;
case '(':
operat[operSub++] = '(';
break;
case ')':
while(operat[operSub-1] != '(')
{
printf("%d %c %d = ", operand[numSub-2], operat[operSub-1], operand[numSub-1]);
operand[numSub-2] = cal(operand[numSub-2], operat[operSub-1], operand[numSub-1]);
printf("%d\n", operand[numSub-2]);
--numSub;
--operSub;
}
--operSub;
break;
default:
tmp = 0;
while(str[i] >= '0' && str[i] <= '9')
{
tmp = tmp * 10 + str[i] - '0';
++i;
}
--i;
operand[numSub++] = tmp;
break;
}
++i;
}
while(numSub > 1 && operSub >= 1)
{
printf("%d %c %d = ", operand[numSub-2], operat[operSub-1], operand[numSub-1]);
operand[numSub-2] = cal(operand[numSub-2], operat[operSub-1], operand[numSub-1]);
printf("%d\n", operand[numSub-2]);
--numSub;
--operSub;
}
result = operand[numSub-1];
free(operand);
free(operat);
return result;
}
int main()
{
char *str = "225/15-20+(4-3)*2";
int result;
printf("计算过程:\n");
result = evaluateExpression(str);
printf("计算结果:result = %d\n", result);
return 0;
}

计算过程:
225 / 15 = 15
15 - 20 = -5
4 - 3 = 1
1 * 2 = 2
-5 + 2 = -3
计算结果:result = -3


供参考
尘缘udbwcso 2011-11-19
  • 打赏
  • 举报
回复
'function' : conversion from 'float ' to 'char ', possible loss of data

先把那几个警告解决了再说
欢欣之雨 2011-11-19
  • 打赏
  • 举报
回复
回复一下顶上去啊。。。
欢欣之雨 2011-11-19
  • 打赏
  • 举报
回复
木有人吗?。。。来个帮看看吧
欢欣之雨 2011-11-19
  • 打赏
  • 举报
回复
另外第142行还有一个问题。。。拜托~~~
用两种方式实现表达式自动计算 对栈的应用 (1)中缀表达式转后缀表达式并计算(扫两遍) 创建一个数组存储输入的计算表达式。另创建一个数组储存将要生成的后缀表达式。创建一个栈储存操作符。 对已存储的表达式数组扫描。 判断当前节点,如果是操作数或’.’,直接加入后缀表达式中,如果是操作符,则比较前一个操作符与当前操作符的优先级。如果前一个操作符的优先级较高,则将前一个操作符加入后缀表达式中,否则将操作符压入操作符栈。 如果遇到左括号’(’,直接入栈;如果遇到右括号’)’,则在操作符栈中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。 当执行完以上操作,发现栈中仍有剩余操作符,则将操作符依次加到后缀表达式中。此时中缀表达式已经转换成了后缀表达式。 对后缀表达式进行计算。 如果后缀表达式为大于0小于9的字符,则将它转换成浮点型数据并存入数栈中。如果遇到操作符,则从数栈中提取两个数,进行相应的运算。依次进行下去,当没有运算符是,运算结束得到最后的结果。 (2)表达式求值(扫一遍) 创建一个数组存储输入的计算表达式。创建两个栈,一个字符型的栈,一个双精度型的栈。分别用来存储字符和数。 对已存储的表达式数组扫描。 判断当前节点,如果是操作数和’.’,将字符型的操作数转换为浮点型的数后存入操作数栈。 如果是操作符则判断操作符的优先级。如果字符栈中已存储符号的优先级小于要存入的字符的优先级,则直接让字符入操作符栈。如果字符栈中已存储符号的优先级大于或等于要存入的字符的优先级,则取出操作符栈中的一个字符和操作数栈中的两个数进行计算,然后将结果存入操作数栈中,同上进行下去,直到字符栈中已存储符号的优先级小于要存入的字符的优先级时,将操作符存入操作符栈中。 当遇到左括号’(’,将左括号直接存入操作符栈中。当遇到右括号’)’,则在操作符栈中反向搜索,并且每搜到一个字符就在操作数栈中取两个数进行相应的计算。然后,将运算结果存入到操作符栈中。如此进行下去,直到遇到左括号结束。将左括号从栈中取出。最后,如果操作符栈中还有符号,就从操作符栈顶开始将操作符取出并从操作数栈顶开始取出两个数字进行计算,将结果存入操作数栈中。重复上述操作直到操作符栈中没有操作符,得到运算结果。

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧