【问题标题】:Program giving correct output, but displaying Runtime error on Hackerrank程序给出正确的输出,但在 Hackerrank 上显示运行时错误
【发布时间】:2020-04-09 22:10:51
【问题描述】:

我被要求评估给定操作的结果。 例如,如果给我一个字符串((6-(2+3))*(3+8/2))^2+3,结果应该是52.0000。 仅给出一位数字 (0 -> 9)。 这是我的教授在 HackerRank 上发布的自定义问题。 我正在使用 CodeBlocks,一切正常,但是当我在 HackerRank 上测试代码时 它给了我一个运行时错误,但在所有测试用例上都显示正确的输出,所以显然它被拒绝了。

我将代码重写了 2 次,结果仍然相同。 我正在使用 C 语言和 Stacks(这是必须的)。 请谁能告诉我为什么我收到运行时错误!? 我仍然是菜鸟: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;
}

【问题讨论】:

  • 我认为这个错误意味着你的程序太慢了。你需要想出一个更快的算法。
  • 失败的输入是什么?您是否使用调试器来跟踪代码并确保它按照您的预期运行?
  • 一般来说,HackerRank 要求你想出聪明的算法,而不是最明显的解决方案。他们将使用导致幼稚算法花费过多时间的输入对其进行测试。
  • 或者我在想 leetcode。我无法让这些挑战网站保持直截了当。
  • 为什么你认为SIZE 应该只有1000?你试过100000000吗?

标签: c stack runtime-error


【解决方案1】:

您的代码正在读取中缀表达式1+2,将其转换为后缀1 2 +,然后扫描并计算后缀字符串以产生结果:3

如果打算计算结果,则没有理由实际生成后缀字符串然后重新扫描它。您可以直接从中缀转到结果。

Infix 函数中,不要将操作数作为字符串写入result,而是像在Postfix 函数中那样将它们添加到stackfloat。当您从堆栈中弹出一个运算符时,不是写入result,而是从stackfloat 弹出操作数,执行操作,然后将结果推回stackfloat。完成后,stackfloat 上应该只剩下一个值,即最终结果。

这是对您的 Infix 函数的简单修改,它使您不必重新扫描字符串。

【讨论】:

    【解决方案2】:

    很抱歉没有早点回复,但问题出在 return 1 在主要功能中:p 尽管看起来很愚蠢,但当我将 return 1 更改为 return 0 时,一切都运行良好 并且该解决方案被 Hackerrank 接受。

    【讨论】:

      最近更新 更多