RPN калькулятор, используя связанный список
У меня проблемы с моим кодом. Кажется, он работает только на однозначное число Int. Я не знаю, как создать функцию, которая работала бы для int больше 9. Также я не знаю, как завершить программу, если строка пуста.
Вот мой код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//stack type
struct node
{
int head;
int *array;
unsigned capacity;
};
struct node* createNode();
int isEmpty();
char pop();
void push(struct node* stack, char op);
int evaluatePostfix();
int main() {
char exp[1000]; // = "5 1 2 + 4 * + 3 -";
printf("Input string:\t");
fgets(exp, 1000, stdin);
for(int i = 1 ; i <= strlen(exp); i++) {
if(exp[i] == '\n') {
exp[i] = '\0';
}
else if (exp[0] == '\n') {
printf("stack is empty\n");
exit(0);
}
}
printf ("%s = %d\n", exp, evaluatePostfix(exp));
return 0;
}
struct node* createNode(unsigned capacity) {
struct node* stack = (struct node*) malloc(sizeof(struct node));
if (!stack) return NULL;
(*stack).head = -1;
(*stack).capacity = capacity;
(*stack).array = (int*) malloc((*stack).capacity *sizeof(int));
if (!(*stack).array) return NULL;
return stack;
}
int isEmpty(struct node *stack) {
return (*stack).head == -1 ;
}
char pop(struct node* stack) {
if (!isEmpty(stack))
return (*stack).array[(*stack).head--] ;
return '$';
}
void push(struct node* stack, char op) {
(*stack).array[++(*stack).head] = op;
}
// The main function that returns value of a given postfix expression
int evaluatePostfix(char* exp) {
// Create a stack of capacity equal to expression size
struct Stack* stack = createStack(strlen(exp));
struct node *stack = createNode(strlen(exp));
if (!stack) return -1;
// Scan all characters one by one
for (int i = 0; exp[i]; ++i){
// If the scanned character is an operand or number,
// push it to the stack.
if ((exp[i])== ' ') continue;
else if (isdigit(exp[i]))
push(stack, exp[i] - '0');
// If the scanned character is an operator, pop two
// elements from stack apply the operator
else
{
int val1 = pop(stack);
int val2 = pop(stack);
switch (exp[i])
{
case '+': push(stack, val2 + val1); break;
case '-': push(stack, val2 - val1); break;
case '*': push(stack, val2 * val1); break;
case '/': push(stack, val2/val1); break;
}
}
}
return pop(stack);
}
1 ответ
Я не могу написать все для вас, но могу указать вам правильное направление. Во-первых, когда кто-то говорит "библиотечная функция XYZ() будет полезна для вас", тогда вы должны прочитать об этой функции на страницах руководства. Например, из оболочки Linux запустите: man atoi
читать о atoi
функция.
Для вашей конкретной задачи она сводится к разбору строк и преобразованию их в числа и операторы. Таким образом, некоторые полезные библиотечные функции:
strtok
: Извлекает строковые токены с разделителями из более длинной строки. Вы можете использовать это, чтобы получить каждый из отдельных входов.atoi
: Это может преобразовать строковое представление числа в его целочисленный эквивалент. Не позволяет проверять ошибки.strtol
: Можно сделать так же, какatoi
(и многое другое), а также позволяет проверять ошибки.
Имея в виду эту информацию, вот фрагмент кода, который может быть полезен для вас:
int evaluatePostfix(char* exp)
{
char *token;
long int number;
/* strtok will keep extracting the next token delimited by space */
while (token = strtok(exp, " ")) {
/* Now parse the token and process it */
if (is_operator(token)) {
/* do operator processing */
} else {
number = strtol(token, NULL, 10);
/* do number processing */
}
}
/* strtok returns NULL when no more tokens. So
we are done when the while loop exits */
}
Обратите внимание, что приведенный выше код не выполняет проверку ошибок на strtol
, Вы, вероятно, хотите сделать это. Прочитайте справочные страницы для strtol
чтобы понять, как для этого делается проверка ошибок.