2015-04-14 8 views
0

Я не могу заставить эту программу работать, это представляет собой двусвязное представление списка дерева выражений. После создания дерева мне нужно оценить результат, но я не могу понять, как это сделать.Оценка постфиксного выражения с использованием дерева выражений в C

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 
typedef struct node 
{ 
    char item; 
    struct node * left; 
    struct node * right; 
}*Btree; 

Btree root; 
void operandFunc(char); 
void operatorFunc(char); 
void push(Btree); 
Btree pop(); 
void infix(Btree); 
void postfix(Btree); 
void prefix(Btree); 
int solve(Btree); 
int calculate(char,int,int); 
int isOperand(char); 
char expression[25]; 
Btree stack[25]; 
int stackPtr = -1; 

int main() 
{ 
    int count = 0; 
    printf("Please enter a postfix expression\n"); 
    while((expression[count++]=getchar())!='\n'); 
    expression[--count] = '\0'; 
    //puts(expression); 

    for(count = 0;expression[count]!='\0';count++) 
    { 
     switch(expression[count]) 
     { 
      case '+': 
      case '-': 
      case '*': 
      case '/': 
      case '^': 
      case '%': 
      case '$': 
       operatorFunc(expression[count]); 
       break; 
      default: 
       operandFunc(expression[count]); 
     } 
    } 
    if(stackPtr != 0) 
    { 
     printf("Incomplete/Incorrect postfix expression given!\n"); 
    } 
    else 
    { 
     printf("\n\nThe result = %d",solve(stack[stackPtr])+'0'); 
     printf("\n\n"); 
     return 0; 
    } 
} 

void prefix(Btree root) 
{ 
    Btree temp = root; 
    if(temp) 
    { 
     printf("%c ",temp->item); 
     prefix(temp->left); 
     prefix(temp->right);   
    } 
} 

void infix(Btree root) 
{ 
    Btree temp = root; 
    if(temp != NULL) 
    { 
     infix(temp->left); 
     printf("%c ",temp->item);  
     infix(temp->right);  
    } 
} 

void postfix(Btree root) 
{ 
    Btree temp = root; 
    if(temp) 
    { 
     postfix(temp->left); 
     postfix(temp->right);  
     printf("%c ",temp->item);  
    } 
} 

void push(Btree root) 
{ 
    stack[++stackPtr] = root; 
} 

Btree pop() 
{ 
    return (stack[stackPtr--]); 
} 

void operandFunc(char var) 
{ 
    Btree root = (Btree)malloc(sizeof(struct node)); 
    root->item= var; 
    root->left= NULL; 
    root->right= NULL; 
    push(root); 
} 

void operatorFunc(char var) 
{ 
    Btree root = (Btree)malloc(sizeof(struct node)); 
    root->item = var; 
    root->right = pop(); 
    root->left = pop(); 
    push(root); 
} 

int solve(Btree root) 
{ 
    Btree temp = root; 
    char num1,num2; 
    char operator; 
    int result; 
    if(temp) 
    { 
     Btree LEFTP = temp->left; 
     Btree RIGHTP = temp->right; 

     if(LEFTP) 
     { 
      if(isOperand(LEFTP->item)) 
      { 
       num1 = LEFTP->item; 
      } 
      else 
      { 
       num1 = solve(LEFTP); 
      } 
     } 

     if(RIGHTP) 
     { 
      if(isOperand(RIGHTP->item)) 
      { 
       num2 = RIGHTP->item; 
      } 
      else 
      { 
       num2 = solve(RIGHTP); 
      } 
     } 

     operator = temp->item; 
     printf("Test 1 = %c, num1 = %c, num2 = %c\n",operator,num1,num2); 
     result = calculate(operator,num1-'0',num2-'0'); 
     printf("Test Result = %d\n",result); 
     temp->item = (result+'0'); 
     printf("Root Item = %c and %d\n",temp->item,temp->item); 
     return result; 
    } 

    return NULL; 
} 

int calculate(char operator,int op1,int op2) 
{ 
    printf("Operator = %c , num1 = %d, num2 = %d\n",operator,op1,op2); 
    switch(operator) 
    { 
     case '+': return(op1+op2); 
        break; 
     case '-': return(op1-op2); 
        break; 
     case '*': return(op1*op2); 
        break; 
     case '/': return(op1/op2); 
        break; 
     case '%': return(op1%op2); 
        break; 
     case '$': return pow(op1,op2); 
        break; 
     default: printf("\n illegal operation."); 
        exit; 
    } 
} 

int isOperand(char var) 
{ 
    switch(var) 
    { 
     case '+': 
     case '-': 
     case '*': 
     case '/': 
     case '$': 
     case '%': 
        return 0; 
     default: 
        return 1; 
    } 
} 

У меня возникли проблемы с преобразованием и возвратом символов в виде целых чисел.

ОБНОВЛЕНИЕ 1: Я смог разрешить ввод одноразрядных цифр, чтобы получить результат с несколькими цифрами. Я все еще работаю над новой структурой данных для вычисления многозначных чисел. Ниже приведен обновленный код.

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 
typedef struct node 
{ 
    char item; 
    struct node * left; 
    struct node * right; 
}*Btree; 

Btree root; 
void operandFunc(char); 
void operatorFunc(char); 
void push(Btree); 
Btree pop(); 
void infix(Btree); 
void postfix(Btree); 
void prefix(Btree); 
int solve(Btree); 
int calculate(char,int,int); 
int isOperand(char); 
char expression[25]; 
Btree stack[25]; 
int stackPtr = -1; 

int main() 
{ 
    int count = 0; 
    printf("Please enter a postfix expression\n"); 
    while((expression[count++]=getchar())!='\n'); 
    expression[--count] = '\0'; 
    //puts(expression); 

    for(count = 0;expression[count]!='\0';count++) 
    { 
     switch(expression[count]) 
     { 
      case '+': 
      case '-': 
      case '*': 
      case '/': 
      case '^': 
      case '%': 
      case '$': 
       operatorFunc(expression[count]); 
       break; 
      default: 
       operandFunc(expression[count]); 
     } 
    } 
    if(stackPtr != 0) 
    { 
     printf("Incomplete/Incorrect postfix expression given!\n"); 
    } 
    else 
    { 
     printf("\n\nThe result = %d",solve(stack[stackPtr])-'0'); 
     printf("\n\n"); 
     return 0; 
    } 
} 

void prefix(Btree root) 
{ 
    Btree temp = root; 
    if(temp) 
    { 
     printf("%c ",temp->item); 
     prefix(temp->left); 
     prefix(temp->right);   
    } 
} 

void infix(Btree root) 
{ 
    Btree temp = root; 
    if(temp != NULL) 
    { 
     infix(temp->left); 
     printf("%c ",temp->item);  
     infix(temp->right);  
    } 
} 

void postfix(Btree root) 
{ 
    Btree temp = root; 
    if(temp) 
    { 
     postfix(temp->left); 
     postfix(temp->right);  
     printf("%c ",temp->item);  
    } 
} 

void push(Btree root) 
{ 
    stack[++stackPtr] = root; 
} 

Btree pop() 
{ 
    return (stack[stackPtr--]); 
} 

void operandFunc(char var) 
{ 
    Btree root = (Btree)malloc(sizeof(struct node)); 
    root->item= var; 
    root->left= NULL; 
    root->right= NULL; 
    push(root); 
} 

void operatorFunc(char var) 
{ 
    Btree root = (Btree)malloc(sizeof(struct node)); 
    root->item = var; 
    root->right = pop(); 
    root->left = pop(); 
    push(root); 
} 

int solve(Btree root) 
{ 
    Btree temp = root; 
    char num1,num2; 
    char operator; 
    int result; 
    if(temp) 
    { 
     Btree LEFTP = temp->left; 
     Btree RIGHTP = temp->right; 

     if(LEFTP) 
     { 
      if(isOperand(LEFTP->item)) 
      { 
       num1 = LEFTP->item; 
      } 
      else 
      { 
       num1 = solve(LEFTP); 
      } 
     } 

     if(RIGHTP) 
     { 
      if(isOperand(RIGHTP->item)) 
      { 
       num2 = RIGHTP->item; 
      } 
      else 
      { 
       num2 = solve(RIGHTP); 
      } 
     } 

     operator = temp->item; 
     printf("Test 1 = %c, num1 = %c, num2 = %c\n",operator,num1,num2); 
     result = calculate(operator,num1-'0',num2-'0'); 
     printf("Test Result = %d\n",result); 
     temp->item = (result+'0'); 
     printf("Root Item = %c and %d\n",temp->item,temp->item); 
     return root->item; 
    } 

    return NULL; 
} 

int calculate(char operator,int op1,int op2) 
{ 
    printf("Operator = %c , num1 = %d, num2 = %d\n",operator,op1,op2); 
    switch(operator) 
    { 
     case '+': return(op1+op2); 
        break; 
     case '-': return(op1-op2); 
        break; 
     case '*': return(op1*op2); 
        break; 
     case '/': return(op1/op2); 
        break; 
     case '%': return(op1%op2); 
        break; 
     case '$': return pow(op1,op2); 
        break; 
     default: printf("\n illegal operation."); 
        exit; 
    } 
} 

int isOperand(char var) 
{ 
    switch(var) 
    { 
     case '+': 
     case '-': 
     case '*': 
     case '/': 
     case '$': 
     case '%': 
        return 0; 
     default: 
        return 1; 
    } 
} 

ответ

0

В operandFunc(expression[count]); вы обрабатываете только один символ. Это означает, что вы не можете работать с многосимвольными операндами, такими как 10 или 123. Если это происходит, вы нажимаете каждую цифру отдельно. Таким образом, ваш язык ограничен одними цифрами (ОК, ваше деление).

В solve вы говорите printf("Root Item = %c and %d\n",temp->item,temp->item); . Здесь второй аргумент должен быть преобразован в int: temp->item-'0'. Это нужно делать, когда вы используете %d в формате printf.

Остальная часть вашего кода выглядит нормально. Может быть, установите более высокий уровень предупреждения при компиляции, чтобы найти больше ошибок?

EDIT/ADDITION: Как обрабатывать многозначные номера?

Следующий фрагмент обрабатывает многозначные номера. Вы должны адаптировать-структуру, чтобы сделать разницу между гольцами и Интсом и изменить operandFunc обрабатывать эти цифры:

while((c=getchar())!='\n') 
{ 
    switch(c) 
    { 
     case '+': 
     case '-': 
     case '*': 
     case '/': 
     case '^': 
     case '%': 
     case '$': 
      operatorFunc(c); 
      break; 
     default: // assume digit(s) 
      num= c-'0'; 
      while ((c=getchar())!='\n' && isdigit(c)) num= num*10+c-'0'; 
      operandFunc(num); 
      ungetc(c,stdin); 
    } 
} 
+0

Как я могу переписать эту программу так, чтобы она могла вычислять больше, чем цифры с одной цифрой, потому что, честно говоря, мой нынешний практически бесполезен. – Wakkun

0

Мы можем оценить выражение постфикса с помощью бинарного дерева, имея в виду два условия

если Eval (корень) является оператором, мы используем рекурсию, Eval (корне-> LLink) + Eval (корне-> RLink) еще мы возвращаем корне-> Информация о - '0'

Функция для оценки

float evaluate(NODE root) 
{ 
    float num; 
    switch(root->info) 
{ 
    case '+' : return eval(root->llink) + eval(root->rlink); 

    case '-' : return eval(root->llink) - eval(root->rlink); 

    case '/' : return eval(root->llink)/eval(root->rlink); 

    case '*' : return eval(root->llink) * eval(root->rlink); 

     case $ : 
     case^: return pow(eval(root->llink) ,eval(root->rlink)); 

     default : if(isalpha(root->info)) 
       { 
        printf("%c" = root->info); 
        scanf("%f",&num); 
        return num; 
       } 
       else 
        return root->info - '0'; 
     } 
}