Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Wczytywanie znaków na stos

Ostatnio zmodyfikowano 2016-03-20 18:20
Autor Wiadomość
szymi_jimi
Temat założony przez niniejszego użytkownika
Wczytywanie znaków na stos
» 2016-03-19 20:59:22
Witam, jestem początkującym programistą. Mam zadanie aby sprawdzić czy podany ciąg znaków jest palindromem korzystając ze stosu. Mam jednak z tym problem z samym wczytywaniem i zdejmowaniem znaków ze stosu, ponieważ na stos wczytuje mi się więcej niż jeden znak, a co lepsze przy wyświetlaniu wyświetlają mi się tylko 4 znaki. Po wpisaniu wyrazu, jeśli uruchomię w pętli wyświetlanie to wyświetla się prawidłowo. Czy mógłby mi ktoś wskazać w którym miejscu popełniam błąd?

Poniżej zamieszczam kod:
C/C++
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>

typedef struct stack_node {
    char data[ 1 ];
    struct stack_node * next;
} node;

node * push( node * top, char * str )
{
    node * new_node =( node * ) malloc( sizeof( node ) );
    if( new_node != NULL ) {
        strcpy( new_node->data, str );
        new_node->next = top;
        top = new_node;
    }
    return top;
}
struct stack_node * pop( struct stack_node ** top )
{
    struct stack_node * next = NULL, * old_top = NULL;
    if( * top != NULL ) {
        next =( * top )->next;
        ( * top )->next = NULL;
        old_top = * top;
        * top = next;
    }
    return old_top;
}

int main( void )
{
    struct stack_node * top = NULL;
    int i;
    char a[ 100 ];
    int dlugosc;
   
    puts( "Podaj slowo" );
    scanf( "%s", a );
    dlugosc = strlen( a );
    printf( "%d", dlugosc );
    for( i = 0; i < dlugosc; i++ )
         printf( "%c\n", a[ i ] );
   
    for( i = 0; i < dlugosc; i++ )
    {
        top = push( top, & a[ i ] );
    }
    while( top )
         printf( "%s\n", pop( & top ) );
   
    puts( "" );
   
    return 0;
}



P-146243
mateczek
» 2016-03-19 21:28:49
1. pytanie czy to musi być C??
2. jeśli może to być c++ to dlaczego nie skorzystać z stosu zaimplementowanego w bibliotece standardowej?? std::stack
3
C/C++
char data[ 1 ] // tu masz tylko jeden znak po jaki czort tablica ??
char znak // tak jak już coś
4
C/C++
strcpy( new_node->data, str ); // do jednego znaku nie używaj tej funkcji ona kopiuje do napotkania  "0" minimum dwa znaki !!!
P-146245
szymi_jimi
Temat założony przez niniejszego użytkownika
» 2016-03-19 21:34:42
Ad. 1. Tak musi być C niestety... A strncpy może być czy nie? Jak nie tego, to czego najlepiej użyć? Czy na pewno wczytuje te znaki na stos?
P-146246
Kajteusz
» 2016-03-20 00:32:47
Cześć,

Nie. Tak jak kolega wcześniej wspomniał niepotrzebnie używasz tablicy do przechowania jednego znaku. Dodatkowo nie przekazujesz jednego znaku tylko wskaźnik. Następnie używasz funkcji strcpy do skopiowania 1 znaku. Jak myślisz jak działa ta funkcja? Ta funkcja przepisuje cały łańcuch znaków aż napotka NULL. W Twoim przepadku przepisze wszystko od danego znaku do końca. Ponieważ w tablicy nie ma na to miejsca to, aż dziwie się, że Ci się program nie wysypuje.
P-146252
mateczek
» 2016-03-20 07:48:46
Z takim stosem jest sporo kombinowania ale jakoś przerobiłem
C/C++
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>

struct stack_node {
    char data;
    stack_node * next = NULL;
    stack_node * old = NULL;
};

void push( stack_node ** top, char znak )
{
    stack_node * new_node =( stack_node * ) malloc( sizeof( stack_node ) );
    new_node->old = * top;
    new_node->next = NULL;
    if( * top )( * top )->next = new_node;
   
    new_node->data = znak;
    * top = new_node;
}
char pop( stack_node ** top )
{
    char znak =( * top )->data;
    stack_node * temp =( * top )->old;
    free( * top );
    * top = NULL;
    ( * top ) = temp;
    if( * top )( * top )->next = NULL;
   
    return znak;
}

int main( void )
{
    struct stack_node * top = NULL;
    int i;
    char a[ 100 ];
    int dlugosc;
   
    puts( "Podaj slowo" );
    scanf( "%s", a );
    dlugosc = strlen( a );
   
    for( i = 0; i < dlugosc; i++ )
    {
        push( & top, a[ i ] );
    }
    while( top )
         cout << pop( & top ) << endl;
   
    return 0;
}
P-146253
mateczek
» 2016-03-20 07:57:01
a  może użyć prostszego stosu ?? zamień sobie cout na printf bo ja za bardzo nie znam składni wyświetlania w C
C/C++
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>

struct stack {
    char data[ 100 ];
    int index = 0;
};

void push( stack * s, char znak )
{
    s->index++;
    s->data[ s->index ] = znak;
   
}
char pop( stack * s )
{
    char znak = s->data[ s->index ];
    s->index--;
    return znak;
}

int main( void )
{
    stack s;
    int i;
    char a[ 100 ];
    int dlugosc;
   
    puts( "Podaj slowo" );
    scanf( "%s", a );
    dlugosc = strlen( a );
   
    for( i = 0; i < dlugosc; i++ )
    {
        push( & s, a[ i ] );
    }
    while( s.index )
         cout << pop( & s ) << endl;
   
    return 0;
}
P-146254
szymi_jimi
Temat założony przez niniejszego użytkownika
» 2016-03-20 14:52:23
mateczek, ten pierwszy program po kilku drobnych składniowych poprawkach działa, tylko ty zrobiłeś to na liście dwukierunkowej mam rozumieć? Ciężko mi pojąć tok rozumowania w tych dwóch funkcjach które dodają i zdejmują ze stosu u ciebie, czy mógłbyś to jakoś wytłumaczyć?
P-146272
mateczek
» 2016-03-20 15:28:41
"to zawsze będzie ciężko pojąć bo masz ** (podwójne wskaźniki).

Spróbuj przerobić swój program zamieniając tablicę char na zwykły char.

Wziąłem kawałek twojego kodu i dołożyłem "old" bo przy ściąganiu ze stosu potrzebny był mi wskaźnik na starszy element :)  ot i cała filozofia (nawet się nie zastanawiałem czy wskaźnik next będzie mi potrzebny). Taki kod zawsze najlepiej zrobić po swojemu.
Pamiętając, że top ma pójść o jeden element wyżej przy odkładaniu i spaść przy zdejmowaniu

C/C++
void push( stack_node ** top, char znak )
{
    stack_node * new_node =( stack_node * ) malloc( sizeof( stack_node ) ); // twój kod
    new_node->old = * top; // obecny top staje się oldem
    new_node->next = NULL; //następnego nie ma
    if( * top )( * top )->next = new_node; //stary top (o ile nie jest pusty) dostaje wskaźnik na nowy top
   
    new_node->data = znak; // element przypisany do pola data
    * top = new_node; // aktualizuje top. top teraz pokazuje nowy element
}
P-146275
« 1 » 2
  Strona 1 z 2 Następna strona