Pop работает только один раз в указанной функции c - PullRequest
0 голосов
/ 23 января 2020

Я реализовал стек как связанный список, и я хотел создать функцию, которая сообщает, в порядке ли скобки, например: (()) это хорошо ()) (плохо. Логические функции c функции не хороши, верно сейчас, но я не знаю, почему pop () работает только один раз. Вот мой код (Stog - это стек, а sljedeci - следующий):

struct stog {
    int x;
    stog *sljedeci;
};

typedef struct stog stog;

stog *top;
char pop() {
    stog *temp;
    temp = (stog*)malloc(sizeof(stog));
    temp = top;
    char n = temp->x;
    top = temp->sljedeci;
    top->x = temp->sljedeci->x;
    free(temp);
    return n;
}



void init() {
    top = NULL;
}

void push(char x) {
        stog *temp;
        temp=(stog*)malloc(sizeof(stog));
        temp->x = x;
        temp->sljedeci = top;
        top = temp;
    }

 void Brackets(const char* msg) {
    char z;
    for (int i = 0; i < strlen(msg); i++) {
        if (msg[i] == '(') {
            push('(');
        }
        if (msg[i]==')'){
            z = pop();
            printf("Bad\n");    
        }       
    }
}

int main() {

    const char* msg = "(())";
    init(); 
    Brackets(msg);
    return 0;
}

Вывод:

Плохо

Это должно быть:

Плохо Плохо

РЕДАКТИРОВАТЬ: добавлены функции init () и pu sh ()

Ответы [ 2 ]

1 голос
/ 24 января 2020

Эта строка в pop не имеет смысла:

top->x = temp->sljedeci->x;

В предыдущей строке вы присваиваете temp->sljedeci для top. Таким образом, элемент x, упомянутый здесь, на самом деле одинаков с обеих сторон, поэтому, если оба значения top и temp->sljedeci не равны нулю, это ничего не делает. Если любой из них равен NULL, вы вызываете неопределенное поведение , потому что вы разыменовываете нулевой указатель. Так что избавьтесь от этой строки.

У вас также есть утечка памяти здесь в pop:

temp = (stog*)malloc(sizeof(stog));
temp = top;

Вы выделяете память и назначаете ее адрес temp, но затем вы немедленно перезаписать этот адрес значением top.

Нет необходимости выделять здесь больше памяти, поэтому удалите вызов malloc.

0 голосов
/ 24 января 2020

Мы, начинающие, должны помогать друг другу. :)

Я выполняю ваше задание впервые в жизни .:)

Для начинающих всегда используйте английские слова sh идентификаторы. В противном случае текст программы может быть нечитаемым.

Непонятно, почему элемент данных x имеет тип int вместо char, хотя стек работает с символами строки.

struct stog {
    int x;
    stog *sljedeci;
};

Тем не менее, вы не показали всю реализацию стека, например, функция pop недействительна. Это приводит к утечке памяти.

Сначала вы выделили память и ее адрес, назначенный указателю temp, и сразу же в следующей строке вы переназначили указатель. Таким образом, выделенная память не будет освобождена.

temp = (stog*)malloc(sizeof(stog));
temp = top;

Этот оператор

top->x = temp->sljedeci->x;

может вызывать неопределенное поведение, если top равно NULL.

Также в функции Brackets этот оператор if

    if (msg[i]==')'){
        z = pop();
        printf("Bad\n");    
    }   

не имеет смысла. Функция всегда будет выводить "Bad", как только встретится символ ')'.

Вот решение, которое я сделал.

#include <stdio.h>
#include <stdlib.h>

struct stack
{
    char c;
    struct stack *next;
};

char * top( struct stack **stack )
{
    return *stack == NULL ? NULL : &( *stack )->c;
}

int push( struct stack **stack, char c )
{
    struct stack *current = malloc( sizeof( struct stack ) );
    int success = current != NULL;

    if ( success )
    {
        current->c = c;
        current->next = *stack;

        *stack = current;
    }

    return success;
}

void pop( struct stack **stack )
{
    if ( *stack )
    {
        struct stack *current = *stack;
        *stack = ( *stack )->next;

        free( current );
    }
}

int empty( struct stack **stack )
{
    return *stack == NULL;
}

void clear( struct stack **stack )
{
    while ( *stack ) pop( stack );
}

int bracket_balance( const char *s )
{
    struct stack *stack = NULL;

    int balanced = 1;

    for ( ; *s && balanced; ++s )
    {
        if ( *s == '(' )
        {
            push( &stack, *s );
        }
        else if ( *s == ')' )
        {
            if ( ( balanced = !empty( &stack ) && *top( &stack ) == '(' ) )
            {
                pop( &stack );
            }
        }
    }

    balanced = balanced && empty( &stack );

    clear( &stack );

    return balanced;
}

int main(void) 
{
    const char * s[] = 
    {
        "", "(", ")", "()", ")(", "( ( ) )", "( )( )", "( ) ) (", "Hello"
    };

    for ( size_t i = 0; i < sizeof( s ) / sizeof( *s ); i++ )
    {
        if ( bracket_balance( s[i] ) )
        {
            printf( "\"%s\" has balanced brackets\n", s[i] );
        }
        else
        {
            printf( "\"%s\" does not have balanced brackets\n", s[i] );
        }
    }       

    return 0;
}

Вывод программы:

"" has balanced brackets
"(" does not have balanced brackets
")" does not have balanced brackets
"()" has balanced brackets
")(" does not have balanced brackets
"( ( ) )" has balanced brackets
"( )( )" has balanced brackets
"( ) ) (" does not have balanced brackets
"Hello" has balanced brackets
...