krk
krk

Reputation: 23

Palindrome using three stacks - only output is "is a palindrome" (java logical error)

i've been looking at every post with the word palindrome, but i haven't come across any with the same sort of issue i'm having...

my goal is to identify palindromes using three stacks - when "madam" is inputted, the output should be "madam is a palindrome" and when "orange" is inputted, the output should be "orange is not a palindrome". i am only able to get the "...is a palindrome" output, no matter what

i'm trying to follow the following algorithm:

  1. push every character into original stack and temporary stack
  2. pop every character off temporary stack and push character into new stack (reverse the order)
  3. compare original stack to reversed stack

the thought process behind this is that every time one of the characters in the original stack don't match the reversed stack, the variable mismatches is incremented and if there is more than zero mismatches, the word entered is a palindrome

here is the code:

import java.util.Scanner;
import java.util.Stack;

public class Palindrome {

    public static boolean is_palindrome(String input) {
        
        Stack<Character> original = new Stack<Character>();
        Stack<Character> reversedStack = new Stack<Character>();
        Stack<Character> tempStack = new Stack<Character>();
        
        Character letter;           //one character from the input string
        int mismatches = 0;         //number of spots that mismatched
        int index;                  //index for the input string
        
        for(index = 0; index < input.length(); index++) {
            
            letter = input.charAt(index);
            
            if(Character.isLetter(letter)) {
                
                original.push(letter);
                tempStack.push(letter);
                
            }
            
            reversedStack.push(tempStack.pop());
            
        }
        
        while(!original.isEmpty()) {
            
            if(!original.pop().equals(reversedStack.pop())) { mismatches++; }
            
        }
        return (mismatches == 0);
        
    }
    
    //main() method, used for testing program
    @SuppressWarnings("resource")
    public static void main(String[] args) {
        
        Scanner input = new Scanner(System.in);         //user input
        String word;                                    //one input line
        
        do {
            
            System.out.print("Enter a word: ");
            word = input.nextLine();
            
            if(is_palindrome(word)) { System.out.println(word + " is a palindrome."); }
            else { System.out.println(word + " is not a palindrome."); }
            
            break;
            
        } while(word.length() != 0);

    }

}

any hints as to why this is only printing "...is a palindrome"?

Upvotes: 0

Views: 110

Answers (3)

rzwitserloot
rzwitserloot

Reputation: 102902

Let's assume that the input is all letters. Then, your initial for loop will:

  1. Push the letter onto original.
  2. Push the letter onto tempStack.
  3. Pop tempStack, and push that onto reversedStack.

In other words, that's just a silly way to do:

  1. Push the letter onto original
  2. Push the letter onto reversedStack
  3. tempStack remains empty.

Clearly not what you want. You need a new, separate while loop for the 'pop tempStack and push into reversedStack' feature.

NB: As a sidenote, this is a crazy complicated algorithm to do the job, but presumably the assignment is to learn about stacks, and to do so by doing a Rube Goldberg machine job. Just in case that wasn't the point, this can be done near trivially by simply looping once, from 0 to half the input length, and comparing the char at index i with the char at index len - i. The entire methods can fit in 4 lines and takes zero objects to get the job done.

Upvotes: 2

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79075

You do not need three stacks. It can be solved using a single stack.

  1. Push each character to a Stack.
  2. Compare the popped characters with the characters of the string from the beginning. Return false as soon as a mismatch is found; otherwise, return true if all characters match.

Demo:

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(isPallindrome("madam"));
        System.out.println(isPallindrome("orange"));
    }

    static boolean isPallindrome(String s) {
        Stack<Character> stack = new Stack<>();
        char[] arr = s.toCharArray();
        for (char c : arr) {
            stack.push(c);
        }

        for (char c : arr) {
            if (c != stack.pop()) {
                return false;
            }
        }

        return true;
    }
}

Output:

true
false

However, if you are free to use any other way to solve it, given below is a simpler way:

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(isPallindrome("madam"));
        System.out.println(isPallindrome("orange"));
    }

    static boolean isPallindrome(String str) {
        return new StringBuilder(str).reverse().toString().equals(str);
    }
}

Output:

true
false

Upvotes: 1

Klemikaze
Klemikaze

Reputation: 378

This is extremely complicated approach! You can decide whether a word is palindrome in just one for loop (and you have to go through just half the word) - compare chars at index i and index length - i, go through Math.floor(wordLength / 2) chars and if you have one mismatch, it's not palindrome - break loop and print fail...

Upvotes: 0

Related Questions