pythonstackpalindrome

Checking a palindrome using stack gives false negative result for single letter


I want to check whether a certain word is a palindrome or not. This is the python code I wrote to check. But it's not giving me the correct result.

Stack class:

class Stack:
    def __init__(self):
        self.items=[]

    def isEmpty(self):
        return self.items==[]

    def push(self,data):
        self.items.append(data)

    def size(self):
        return len(Self.items)

    def show(self):
        print (self.items)

    def peek(self):
        return self.items[len(self.items)-1]

    def pop(self):
        assert not self.isEmpty()
        return self.items.pop()

The program:

a= input("Enter a word: ")

s=Stack();

for i in a:
    s.push(i);
    list1 = s.pop();

if(list1 == a):
    print("The word is a palindrome");
else:
    print("It's not a palindrome");
    print(a);
    print(list1);

It will give me the output as follows:

>>> 
 RESTART: C:/Users/Dil/AppData/Local/Programs/Python/Python36-32/Tutorials/checkpalindrome.py 
Enter a word: kayak
It's not a palindrome
kayak
k
>>> 

Solution

  • The output at the end of your question makes it pretty clear why this is happening. a contains the string kayak, while list1 contains a single letter: k. This is because the line list1 = s.pop() reassigns list1 to a single letter each time it is called. You need to append to list1 instead of overwriting it. As Phydeaux notes, the proper way to do this is to define list1 before the loop as an empty string like so: list1 = "". And then in the loop, append to it like so: list1 += s.pop().

    However, there's another issue, namely that having s.push(i) and list1 += s.pop() in the same loop will copy the string in order, rather than in reverse order. This is because you are adding a single item to your stack and immediately emptying it on every loop iteration. What you should do is make your calls to s.push() in one loop, and then the list1 += s.pop() calls in a second loop to get the reversed string.

    Try this out:

    for i in a:
      s.push(i)
    
    list1 = ""
    while not s.isEmpty():
      list1 += s.pop()
    

    As a side note: python doesn't require semicolons at the end of a line. I realize you're likely going through a tutorial for data structures, but a pythonic way to check for a palindrome would be return a == a[::-1].