Обратная польская запись в Си
Мне нужна помощь в реализации моего кода. Вот код на C. Моё задание - создать программу для обратной польской записи. Вот что у меня так далеко. Одна ошибка, которую я имею сразу, - "контроль может достигнуть конца не пустой функции". После ошибки я не уверен, куда идти дальше. Любая помощь будет очень полезна.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
typedef struct node
{
int datum;
int isOperator;
struct node* left;
struct node* right;
}*Node;
Node BuildTree(char** argv, int* index);
int isOperator(char ch);
int isadd(int);
int evaluate(Node);
void infix(Node, int);
int main(int argc, char* argv[])
{
int i = 9; //argc - 1;
Node tree = NULL;
char* debugList[] = {NULL,"2","9","+","5","-", "6", "D", "3", "X"};
tree = BuildTree(debugList, & i);
infix(tree, 43);
printf("\n%d", evaluate(tree));
return 0;
}
Node BuildTree(char** argv, int* index)
{
Node node;
if (*index < 1)
return NULL;
if(isOperator(argv[*index][0]))
{
//insert to the right
node = (Node) malloc(sizeof(Node));
node -> datum = (int) argv[*index][0];
(*index)--;
node -> right = BuildTree(argv, index);
node -> left = BuildTree(argv, index);
node -> isOperator = 1;
return node;
}
else
{
node = (Node) malloc(sizeof(Node));
node -> right = NULL;
node -> left = NULL;
node -> datum = (int) argv[*index][0];
node -> isOperator = 0;
(*index)--;
return node;
}
}
// Return true if ch is a operator, otherwise false
int isOperator(char ch)
{
if (ch == '+' || ch == '-' || ch == 'D' || ch == 'X')
return 1;
else
return 0;
}
void infix(Node node, int c){
if(node == NULL)
return;
else if (isadd(node -> datum) && !isadd(c)){
printf("(");
infix(node -> left, node -> datum);
printf("%c", (char) node -> datum);
infix(node -> right, node -> datum);
printf(")");
}
else {
infix(node -> left, node -> datum);
printf("%c", (char) node -> datum);
infix(node -> right, node -> datum);
}
}
int isadd(int c)
{
if(c == 43 || c == 45)
return 1;
else
return 0;
}
int evaluate(Node node)
{
if(node -> isOperator)
{
switch(node -> datum)
{
case 43:
return evaluate(node -> left) + evaluate(node -> right);
case 45:
return evaluate(node -> left) - evaluate(node -> right);
case 68:
return evaluate(node -> left) / evaluate(node -> right);
case 88:
return evaluate(node -> left) * evaluate(node -> right);
}
}else{
return node -> datum - 48;
}
}
2 ответа
Ваш if, else
имеет return
следующий else
, но никто не следует if
то, что компилятор может гарантировать, будет выполнено. Поэтому, если ваша функция выполняет if
ветвь, функция не имеет return
, Легко исправить - добавить один как default
дело. Таким образом, у вас есть гарантированное исполнение return
по тому пути, который может распознать компилятор. Что-то по линии return -1; /* operator not recognized */
Если у вас уже есть входные данные в RPN, то все, что вам нужно, это стек операндов и конструкция большого переключателя (или if-elseif), где вы оцениваете операторы.
Я вижу, что вы конвертируете нотацию постфикса (RPN) в инфикс (в частности, в дерево выражений), однако оценка RPN намного проще, чем обход дерева.
Я не буду изобретать велосипед, посмотрите реализацию здесь: http://rosettacode.org/wiki/Parsing/RPN_calculator_algorithm
Переменная s
содержит вход. rpn
Функция начинается с токенизатора (в вашем коде его нет). Если ввод неправильный (недопустимое выражение RPN), die()
Функция будет вызвана с кратким объяснением.