2015-04-07 80 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值以用作符號索引。