2015-04-07 56 views
1
#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函数中,但它不会说哪一行,我不知道在哪里。有谁知道为什么这会seg段?从中缀到后缀

回答

1

你已经做了错误的几件事:

if(isNumeric(&symbol) != 1) 

功能isNumeric()需要一个空值终止字符串作为输入,而不是指向单个字符。

 strcat(postfix, &symbol); 

这里同样适用。

 strcat(postfix, &next); 

我猜这也是错误的。如果你想打开一个字符转换成字符串,你可以这样做:

char temp[2] = {0}; 

temp[0] = symbol; 
strcat(postfix, temp); 
0
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 }; 

然后测试一个字符是否是运营商:

#include <string.h> 
if (strchr(operators, chr)) 
    ...; 

并获得优先变为:

p = precedence[strchr(operators, chr) - operators]; 

如果有更多的价值与运营商联系起来,我d考虑使用X宏来生成一个表格和一组相关联的enum值以用作符号索引。