Палиндром Использование стека - PullRequest
7 голосов
/ 13 декабря 2010

Наш профессор потребовал от нас проверить, является ли слово палиндромом, используя стеки. Каждый раз, когда я запускаю его, появляется ошибка: Unhandled Exception. Access violation Что я делаю не так? Как я могу улучшить свой код? Мой код выглядит следующим образом:

 typedef struct stack{
    char name;
    struct stack * next;
}Stack;

void push(Stack**head, char value);
char pop(Stack**head);


int main(){
   char word[11];
   int i=0;
   int lenght = 0; 
   Stack*head = NULL;
   printf("Please type the word: ");
   scanf("%s", word);
   lenght = strlen(word);
   while(word[i]!='\0'){
       push(&head, word[i]);
       i++;
   }
   i = 0;
   while(pop(&head)==word[i]){
       i++;
   }
   if(i==lenght) printf("The word is a palindrome");
   else printf("The word is not a palindrome");
}

Ответы [ 6 ]

7 голосов
/ 13 декабря 2010

Ваша push функция должна принимать

  • адрес заголовка стека (правильно) и
  • символ, который необходимо вставить (для этого нужноисправление).

Таким образом, сигнатура метода становится:

void push(Stack**head, char value);

, и в теле функции вы добавляете value к вершине стека как:

temp->name = value;

Кроме того, вы всегда должны проверять возвращаемое значение malloc.

Поскольку вы возвращаете извлеченное значение из функции pop, тип возвращаемого значения не должен быть void, измените его наchar в объявлении и определении как:

char pop(Stack**head)

Существует еще одна логическая ошибка:

Для начала вставьте все символы ввода в стек.Далее вы начинаете совать персонажей.Там нет завершающего условия для вашего появления.Когда вы вытолкнули все символы (поэтому ваш стек пуст), следующий вызов pop приведет к сбою, так как вы будете разыменовывать указатель NULL (*head будет NULL).

Чтобы исправить это, вы должны вытолкнуть только те символы, которые нажали, выполнив:

while(i<lenght && pop(&head)==word[i]){

Поскольку && замкнут накоротко, pop не будет вызываться после того, как вы нажметевсе символы.

В качестве альтернативы (и предпочтительного подхода) нужно написать другую функцию с именем isEmpty, которая возвращает true / 1, когда стек пуст, и использовать этот метод перед вызовом popспособ.

2 голосов
/ 13 декабря 2010

Вы также можете рассмотреть возможность использования "рекурсии", которая чем-то похожа на конструирование стека, просто это делается неявно для вызовов вашего метода.
Проблема палиндрома - это классическое упражнение для изучения силы рекурсии:)

2 голосов
/ 13 декабря 2010

вы должны проверить, богатый конец стека или нет в коде:

while(i < length && pop(&head)==word[i]){
       i++;
   }
2 голосов
/ 13 декабря 2010

Я думаю, вы должны изменить 'void pop (Stack ** head) {' на

char pop(Stack **head) {

, а также защитить от пустого стека:

char pop(Stack**head){
Stack* temp;
char val;
temp = *head;
if (!temp) return 0;
val = temp->name;
*head = (*head)->next;
free(temp);
return val;
}
1 голос
/ 13 декабря 2010

Ваш код получил проблему на while-pop части.

Для вашего удобства я приложил для вас измененный рабочий код:

typedef struct stack{
    char name;
    struct stack * next;
}Stack;

void push(Stack**head, char value);
char pop(Stack**head);



int main (int argc, const char * argv[]) {


    char word[11];
    int i=0;
    int lenght = 0; 
    Stack*head = NULL;
    printf("Please type the word: ");
    scanf("%s", word);
    lenght = strlen(word);
    while(word[i]!='\0'){
        push(&head, word[i]);
        i++;
        }

    //i = 0;
    //while(pop(&head)==word[i]){
    //  i++;
    //}

    int counter=0;
    i=0;
    for (counter=0; counter<lenght; counter++) {
    if (pop(&head) == word[counter])
    {
        i++;
    }
    }


    if(i==lenght) printf("The word is a palindrome");
    else printf("The word is not a palindrome");


    return 0;
}

void push(Stack**head,char value){

    Stack *temp = (Stack*)malloc(sizeof(Stack));
    temp->name = value;
    temp->next = *head;
    *head = temp; 
}

char pop(Stack**head){

    Stack* temp;

    char val;
    temp = *head;
    val = temp->name;
    *head = (*head)->next;

    free(temp);
    return val;
}
1 голос
/ 13 декабря 2010

Эта функция, как вы ее называете:

push(&head, i, word[i]);

Это объявленная и определенная функция:

void push(Stack**head, int i, char value[i]);

Таким образом, аргумент 3 в объявлении является массивом символов, тогда как аргумент 3 в вызывающей части является символом. Измените push(), чтобы использовать символ для value, и просто опустите i:

void push(Stack**head, char value){
    Stack *temp = (Stack*)malloc(sizeof(Stack));
    temp->name = value;
    temp->next = *head;
    *head = temp; 
}

Теперь назовите его с помощью:

push(&head, word[i]);
...