[英]Going from infix to postfix
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "stack.h"
#define MAX_EQU_LEN 100
static int prec(char operator)
{
switch (operator)
{
case '*':
return 5;
case '/':
return 4;
case '%':
return 3;
case '+':
return 2;
case '-':
return 1;
default:
break;
}
return 0;
}
static int isNumeric(char* num)
{
if(atoi(num) == 0)
{
return 0;
}
return 1;
}
char* infix_to_postfix(char* infix)
{
char* postfix = malloc(MAX_EQU_LEN);
stack* s = create_stack();
s->size = strlen(infix);
node* tempPtr = s->stack;
unsigned int i;
char symbol,next;
for(i = 0; i < s->size ; i++)
{
symbol = *((infix + i));
tempPtr = s->stack;
if(isNumeric(&symbol) != 1)
{
strcat(postfix, &symbol);
}
else if(symbol == '(')
{
push(s, symbol);
}
else if(symbol == ')')
{
while(s->size != 0 && top(s) != '(')
{
next = tempPtr->data;
pop(s);
strcat(postfix, &next);
tempPtr = s->stack;
if(tempPtr->data == '(')
{
pop(s);
}
}
}
else
{
while(s->size != 0 && prec(top(s)) > prec(symbol))
{
next = tempPtr->data;
pop(s);
strcat(postfix, &next);
push(s,next);
}
}
while(s->size != 0)
{
next = tempPtr->data;
pop(s);
strcat(postfix, &next);
}
}
return postfix;
}
int evaluate_postfix(char* postfix) {
//For each token in the string
int i,result;
int right, left;
char ch;
stack* s = create_stack();
node* tempPtr = s->stack;
for(i=0;postfix[i] < strlen(postfix); i++){
//if the token is numeric
ch = postfix[i];
if(isNumeric(&ch)){
//convert it to an integer and push it onto the stack
atoi(&ch);
push(s, ch);
}
else
{
pop(&s[i]);
pop(&s[i+1]);
//apply the operation:
//result = left op right
switch(ch)
{
case '+': push(&s[i],right + left);
break;
case '-': push(&s[i],right - left);
break;
case '*': push(&s[i],right * left);
break;
case '/': push(&s[i],right / left);
break;
}
}
}
tempPtr = s->stack;
//return the result from the stack
return(tempPtr->data);
}
该文件是程序的一部分,该程序使用堆栈结构对输入文件执行后缀缀。 其他功能已经过测试并且可以正常工作,但是当我尝试添加此部分并实际执行操作时,程序分段错误。 调试器说它发生在infix_to_postfix函数中,但是它没有说出哪一行,我也不知道在哪里。 有谁知道这会导致段错误吗?
您做错了几件事:
if(isNumeric(&symbol) != 1)
函数isNumeric()
期望将一个以空终止的字符串作为输入,而不是指向单个字符的指针。
strcat(postfix, &symbol);
这里同样适用。
strcat(postfix, &next);
我猜这也是错误的。 如果要将单个字符转换为字符串,可以执行以下操作:
char temp[2] = {0};
temp[0] = symbol;
strcat(postfix, temp);
static int isNumeric(char* num)
{
if(atoi(num) == 0)
{
return 0;
}
return 1;
}
如果字符串为"0"
怎么办? 考虑改用strtol
因为它提供了测试结果是否成功的更强大的方法。
无关的风格注释:我的第一个功能看起来过于复杂。 尽管我做的方法很可能也过于复杂。
static int prec(char operator)
{
switch (operator)
{
case '*':
return 5;
case '/':
return 4;
case '%':
return 3;
case '+':
return 2;
case '-':
return 1;
default:
break;
}
return 0;
}
如果函数执行从一组到另一组的简单映射,则通常可以更简单(更快)地执行数组查找。 因此,我将从输入字符的字符串开始。
char *operators = "*" "/" "%" "+" "-";
请注意,编译器会将它们连接为带有空终止符的单个字符串值。
int precedence[] = { 5, 4, 3, 2, 1, 0 };
然后测试char是否是运算符是:
#include <string.h>
if (strchr(operators, chr))
...;
获得优先级变为:
p = precedence[strchr(operators, chr) - operators];
如果还有更多要与运算符关联的值,我会考虑使用X-Macro生成表和一组关联的enum
值以用作符号索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.