Программа выдает правильный вывод, но отображает ошибку времени выполнения на Hackerrank - PullRequest
0 голосов
/ 10 апреля 2020

Меня просят оценить результат данной операции. например, если мне дана строка ((6-(2+3))*(3+8/2))^2+3, результат должен быть 52.0000. даются только цифры с одной цифрой (0 -> 9). Это моя проблема, которую мой профессор разместил на HackerRank. Я использую CodeBlocks, и все работает без сбоев, но когда я тестирую код на HackerRank, он выдает ошибку времени выполнения и все же отображает корректный вывод во всех тестовых примерах, поэтому, очевидно, он был отклонен.

Я переписал код 2 раза и все тот же результат. Я использую C язык и стеки (это обязательно). Может кто-нибудь сказать мне, почему я получаю ошибку во время выполнения !? Я все еще нуб: p, заранее извините за любые очевидные ошибки.

Вот код:

#include<stdio.h>
#include<math.h>
#define SIZE 1000

typedef char element;
typedef struct stack{

    element e[SIZE];
    int top;
}stack;

typedef struct stackFloat{

    float e[SIZE];
    int top;
}stackFloat;

stack createStack(){

    stack newStack;
    newStack.top = -1;
    return newStack;
}

stackFloat createStackFloat(){

    stackFloat newStack;
    newStack.top = -1;
    return newStack;
}

int isFullStack(stack p){

    if(p.top == SIZE - 1)
        return 1;
    return 0;
}

int isEmptyStack(stack p){

    if(p.top == -1)
        return 1;
    return 0;
}

int isEmptyStackFloat(stackFloat p){

    if(p.top == -1)
        return 1;
    return 0;
}

int pushFloat(stackFloat *p, float data){

    p->e[++p->top] = data;
    return 1;
}

int topFloat(stackFloat p, float *Top){

    if(isEmptyStackFloat(p))
        return 0;
    *Top = p.e[p.top];
    return 1;
}

int popFloat(stackFloat *p){

    if(isEmptyStackFloat(*p))
        return 0;
    p->top--;
    return 1;
}

int push(stack *p, element data){

    if(isFullStack(*p))
        return 0;
    p->e[++p->top] = data;
    return 1;
}

int top(stack p, element *Top){

    if(isEmptyStack(p))
        return 0;
    *Top = p.e[p.top];
    return 1;
}

int pop(stack *p){

    if(isEmptyStack(*p))
        return 0;
    p->top--;
    return 1;
}

int stackable(char o1, char o2){
    switch (o1) {
        case '(': return 1;
        case '+': case '-': return (o2 == '(');
        case '#': return (o2 != '#');
        case ')': return (o2 == '(');
        case '*':case '/': return (o2 == '(' || o2 == '+' || o2 == '-');
        case '^': return (o2 != '#' && o2 != '^');
    }
    return 0;
}

char *Infix(char A[]){

    char result[SIZE], e;
    int counter = 0, i = 0;
    stack p = createStack();

    for(i=0; A[i]; i++){

        if(A[i] >= '0' && A[i] <= '9'){
            result[counter++] = A[i];
            continue;
        }
        else
            if(isEmptyStack(p)){
                push(&p, A[i]);
                top(p, &e);
        }
        else{
            top(p, &e);
            if(!stackable(A[i], e)){
                while(!stackable(A[i], e)){

                    result[counter++] = e;
                    pop(&p);
                    if(isEmptyStack(p))
                        break;
                    top(p, &e);
                }
            }

            if(A[i] != ')'){
                push(&p, A[i]);
                top(p, &e);

            }else{
                pop(&p);
                top(p, &e);
            }
        }
    }

    while(!isEmptyStack(p)){
        top(p, &e);
        result[counter++] = e;
        pop(&p);
    }

    result[counter] = '\0';
    for(int i=0; i<=counter; i++){
        A[i] = result[i];
    }

    return A;
}

int isOperator(char op){
    if(op == '+' || op == '-' || op == '*' || op == '/' || op == '#' || op == '^')
        return 1;
    return 0;
}

stackFloat Postfix(char str[]){

    stackFloat p = createStackFloat();
    int i = 0, empty = 0;
    float result = 0, conv = 0, e = 0;
    float num1 = 0, num2 = 0;

    for(i=0; str[i]; i++){
        if(!isOperator(str[i])){
            conv = str[i] - '0';
            pushFloat(&p, conv);
        }
        else{
            topFloat(p, &e);
            popFloat(&p);
            num1 = e;
            if(isEmptyStackFloat(p)){
                empty = 1;
            }

            if(str[i] == '#'){
                result = num1 * (-1);

            }else{
                topFloat(p, &e);
                popFloat(&p);
                num2 = e;
            }

            switch(str[i]){

                case '+': result = num2 + num1;
                        break;
                case '-': result = num2 - num1;
                        if(empty && num2 == 0)
                            result = num1*(-1);
                        break;
                case '*': result = num2 * num1;
                        break;
                case '/': result = num2 / num1;
                        break;
                case '^': result = (float)pow(num2, num1);
                        break;
                default:
                        break;
            }
            pushFloat(&p, result);
            num1 = 0; num2 = 0;
        }
    }
    return p;
}

int main() {

    int test=0, i=0;
    stackFloat result = createStackFloat();
    char str1[SIZE];
    char *str2;
    scanf("%d ", &test);

    for(i=0; i<test; i++){
        scanf("%s", str1);
        str2 = Infix(str1);
        result = Postfix(str2);
        printf("%.4f\n", result.e[result.top]);
    }

    return 1;
}

1 Ответ

0 голосов
/ 11 апреля 2020

Ваш код читает инфиксное выражение, 1+2, преобразует его в постфикс 1 2 +, затем сканирует и оценивает строку постфикса, чтобы получить результат: 3.

Если целью является Вычислите результат, нет никакой причины на самом деле создать строку постфикса, а затем пересмотреть ее. Вы можете go непосредственно из инфикса к результату.

В вашей функции Infix вместо записи операндов в result в виде строки добавьте их в stackfloat, как в Postfix функция. Когда вы извлекаете оператор из стека, вместо записи в result, вы выталкиваете операнды из stackfloat, выполняете операцию и возвращаете результат * stackfloat. Когда вы закончите, в stackfloat должно остаться только одно значение, которое является окончательным результатом.

Это простая модификация вашей функции Infix, которая избавляет вас от необходимости повторно отсканируйте строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...