0

I am working on palindrome detector in C++ that reads in a file and marks the lines that are palindromes with the indicator "*". Here's what I have.

PalindromeDetector::PalindromeDetector(const string& iFile, const string& oFile) {
myInFile = iFile;
myOutFile = oFile;
}

void PalindromeDetector::detectPalindrome() {
    ifstream fin(myInFile.data());
    ofstream fout(myOutFile.data());
    string nLine, palLine;
    while (getline(fin, nLine)){
        if (isPalindrome(nLine)){
            fout << nLine << " ***";
        } else {
            fout << nLine;
        }
    }
    fin.close();
    fout.close();
}

bool PalindromeDetector::isPalindrome(const string& str) {
    Stack<char> charStack(1);
    ArrayQueue<char> charQueue(1);
    char ch1, ch2;
    for ( unsigned i = 0; i < str.size(); i++){
        if (isalnum (str[i])){
            tolower(str[i]);
            try {
                charStack.push(str[i]);
                charQueue.append(str[i]);
            } catch ( StackException& se ){
                charStack.setCapacity(charStack.getCapacity() * 2);
                charQueue.setCapacity(charQueue.getCapacity() * 2);
                charStack.push(str[i]);
                charQueue.append(str[i]);
            }
        } else {
            while ( !charStack.isEmpty() || !charQueue.isEmpty() ){
                ch1 = charStack.pop();
                ch2 = charQueue.remove();
                if ( ch1 != ch2 ){
                    return false;
                }
            }
        }
    }
    return true;
}

I'm having 2 problems with this so far: 1. It isn't correctly outputting the file with the "*" at the end of the line; it's doing it at the front for some reason. 2. It only marks the first line in each block of the file, not the lines that are palindromes. I would really appreciate some help on this.

user3020033
  • 15
  • 2
  • 10

1 Answers1

2

Why are you making isPalidrome so complicated?

Could be done as thus

bool isPalidrome(const string &s) {
    int left = 0;
    int right = s.length() - 1;
    while (left < right) {
       if (s[left] != s[right]) return false;
       left++; right--;
    }
    return true;
}

Of course you might what to add case-insensitivity

EDIT

Using the more silly way of stacks and queues

bool isPalidrome(const string &s) {
   // Put everything on both
    std::stack<char> lifo;
    std::queue<char> fifo;
    unsigned int loop;
    for (loop = 0; loop < s.length); ++loop) {
      lifo.push(s[loop]);
      fifo.push(s[loop]);
    }
    // Note stack and queue the characters are in reverse order from each other
    for (loop = 0; loop < s.length); ++loop) {
       if (lifo.pop() != fifo.pop()) return false;
    }
    return true;
}
Ed Heal
  • 59,252
  • 17
  • 87
  • 127
  • Probably because he has to use provided classes for it (stacks and queues, etc): http://stackoverflow.com/questions/23255996/c-using-a-stack-to-determine-if-a-c-style-string-is-a-palindrome – Steve Apr 24 '14 at 23:40
  • So why not use those classes to read and store __file__ information, instead of using them inside the `isPalindrome` function? – Paweł Stawarz Apr 24 '14 at 23:46
  • @PawełStawarz - Do you understand the comment – Ed Heal Apr 24 '14 at 23:52
  • @EdHeal But why would I put every char on the queue and stack? I only need to compare ones that are alphanumeric. – user3020033 Apr 24 '14 at 23:59
  • @user3020033 - Easy bit - modify the algorithm to only consider the alphanumerics. The names LIFO and FIFO for the variables gives it away. Last in first out compared to first in first out. i.e. comparing last with the first. – Ed Heal Apr 25 '14 at 00:17
  • @EdHeal Hmmm...Your suggestion is not working for me either. Could you tell me if there's maybe something wrong with my dectectPalindrome()? – user3020033 Apr 25 '14 at 00:26