isPalindrome()

I need help to create a function() in QT5 using QString to check if a sentence is a palindrome and must say Yes if it is and no if it is not. important it must NOT be case sensitive

e.g) Sam I am is not a palindrome.
e.g) All for one and one for all is a palindrome.

I have been stuck on this for 4 days now and all the examples I find don't work with QT5 QString and only checks if one word is a palindrome.
Last edited on
Instead of trying to find an example that you can just copy, try to understand the algorithm and then try to write it yourself with QString. If there is something you don't know how to do with a QString (e.g. getting the length of the string or accessing a certain character) just look it up, in the documentation or elsewhere.

https://doc.qt.io/qt-5/qstring.html

Last edited on
I have been on that site so many times, work better (learn better) from examples as I can physically see where what is used and is found. when I read these generic codes it does not make any sense to me
First of all, how is a "palindrome" for a sentence defined exactly?

Wikipedia shows us these examples:
Madam, I’m Adam.
A man, a plan, a canal – Panama.
Never odd or even.


Not only character case is ignored, but also spaces and "special" characters are completely ignored!

So, first of all, you will have to create a "normalized" version of the given input string, in which spaces and "special" characters have been removed, and all characters have been converted to lower case.

Then you can reverse the "normalized" string and compare it to the non-reversed "normalized" string.
Last edited on
all the examples I find don't work with QT5 QString


I suspect these were either for c using null-terminated chars or for C++ using std::string - not using QT's non-standard string class.

To check that a string is a palindrome, there is no need to reverse. Have two pointers - one to beginning, one to end. Check that both pointers-to chars are the same. If yes, the inc the begin pointer and dec the end pointer and check again. Repeat until either they are equal or end is less then begin pointer. Easy in c++ with std::string using .begin() and .rbegin() (or indexes).



Last edited on
Well, I don't know anything about QT, but for C++ish see below.

Looks for word palindromes, not character-by-character palindromes.

Expect the "static_cast<unsigned char> std::" brigade to complain.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <sstream>
#include <cctype>
#include <string>
#include <vector>
using namespace std;

//======================================================================

vector<string> split( const string &str )
{
   // Keep spaces, alphabetic chars and numbers only
   stringstream ss;
   for ( char c : str )
      if ( isspace( c ) || isalnum( c ) ) ss << (char)tolower( c );

   // Split into words
   vector<string> result;
   for ( string word; ss >> word; ) result.push_back( word );

   return result;
}

//======================================================================

bool isWordPalindrome( const vector<string> &words )
{
   for ( int i = 0, j = words.size() - 1; i < j; i++, j-- )
   {
      if ( words[i] != words[j] ) return false;
   }
   return true;
}

//======================================================================

int main()
{
   string tests[] = { "Sam I am", "ALL FOR ONE <and> one for all!", "one two three" };
   for ( string &s : tests ) cout << '"' << s <<  '"' << ( isWordPalindrome( split( s ) ) ? " is " : " is not " ) << "a word palindrome\n";
}


"Sam I am" is not a word palindrome
"ALL FOR ONE <and> one for all!" is a word palindrome
"one two three" is not a word palindrome

Last edited on
As C++, then possibly something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <iomanip>
#include <cctype>

std::vector<std::string> split(const std::string& str) {
	std::stringstream ss;

	for (unsigned char c : str)
		if (isspace(c) || isalnum(c))
			ss << static_cast<char>(tolower(c));

	std::vector<std::string> words;

	for (std::string word; ss >> word; words.push_back(std::move(word)));
	return words;
}

bool isWordPalindrome(const std::vector<std::string>& words) {
	for (size_t b {}, e {words.size() - 1}; b < e; ++b, --e)
		if (words[b] != words[e])
			return false;

	return true;
}

int main() {
	const std::string sents[] {"Sam I am", "ALL FOR ONE 'and' one for all!"};

	for (const auto& s : sents)
		std::cout << std::quoted(s) << " is " << (isWordPalindrome(split(s)) ? "" : "not ") << "a word palindrome\n";
}


but will this works with QString....


"Sam I am" is not a word palindrome
"ALL FOR ONE 'and' one for all!" is a word palindrome

Last edited on
Thank you will do so, I will see if I can try to integrate it into QT
DayleCom wrote:
I have been on that site so many times, work better (learn better) from examples as I can physically see where what is used and is found. when I read these generic codes it does not make any sense to me

That is totally understandable but you implied you had already found examples so I thought you could learn from those. Being able to look at text descriptions, pseudo code, examples, etc. and then use that to code something slightly different that suits your needs is a valuable skill to learn. You will not always find exact instructions for how to do things.
Last edited on
Peter87 (10262)
DayleCom wrote:
I have been on that site so many times, work better (learn better) from examples as I can physically see where what is used and is found. when I read these generic codes it does not make any sense to me

That is totally understandable but you implied you had already found examples so I thought you could learn from those. Being able to look at text descriptions, pseudo code, examples, etc. and then use that to code something slightly different that suits your needs is a valuable skill to learn. You will not always find exact instructions for how to do things.

____________________________________________________________________________
All the examples that I have found only work through a normal editor, but we need to do it in QT4 and we have to use QString, it seems to work differently.
when I read these generic codes it does not make any sense to me


It is usually ease-ish to read and get some understanding from looking at generic codes to see the basis of the algorithm. Once you have an understanding of that, then you can concentrate on the implementation details for the specific language required. It is often fairly easy to turn these generic codes into a program of the required language - even if that is not then the 'best' implementation. Once you done that and understand that, then start using language-specific features to 'fine-tune' the code for that language. But the understanding should come first and is the most important.

If you know the 'method' of determining whether is palindrome or not, then you should be able to express that 'method' in the required language - and be able to extend that 'method' to cover various situations which may not be covered by the 'generic' base code.

In explaining how to develop a 'method' to solve various problems, my preferred book is How To Solve It By Computer by R. G. Dromey. It goes into quite detailed explanations as to how various methods are developed. Unfortunately it is quite an old book (1982) and the code is based upon Pascal (which was a dominant language back then) - but IMO it's an 'easy' read.

https://www.amazon.co.uk/Computer-Prentice-Hall-international-computer-science/dp/0134339959/ref=sr_1_2

Does anyone know/recommend of a more recent similar book?

I know about 'Hackers Delight' - but that is a much more formal/theory driven mainly around numeric methods (but is based around C).

https://www.amazon.co.uk/Hackers-Delight-Henry-S-Warren/dp/0321842685/ref=sr_1_1
Expect the "static_cast<unsigned char> std::" brigade to complain.


lol :) :)

L14 - just change char to unsigned char
QString has QChar, which in turn has QChar::isLetter(), QChar::toLower(), etc.
Perhaps QString::append() and/or some reverse iterators for more fun.
Oh, and the std::reverse() ...
Thank you to everyone that helped me I came right but for all of your references I have included the code that I required:

bool SentenceProcessor::isReversible(QString sentence)
{
bool isRev = false;
QStringList sl, rl;
sl = sentence.toLower().split(" ");

for (int count = 0; count < sl.length(); count++)
{
rl.push_front(sl.at(count));
}

if (sl == rl )
{
isRev = true;
}

return isRev;
}
Please use code tags when posting formatted code so that the code is readable


[code]
formatted code goes here
[/code]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool SentenceProcessor::isReversible(QString sentence) {
	bool isRev = false;
	QStringList sl, rl;

	sl = sentence.toLower().split(" ");

	for (int count = 0; count < sl.length(); count++) {
		rl.push_front(sl.at(count));
	}

	if (sl == rl) {
		isRev = true;
	}

	return isRev;
}

1
2
3
4
5
6
def isReversible( sentence ):
    sl = sentence.lower().split()
    return sl == sl[::-1]

tests = [ "Sam I am", "All for    one and one for all" ]
for s in tests: print( s, "===>", isReversible( s ) )


Sam I am ===> False
All for    one and one for all ===> True


Needs the C++ versions to obliterate punctuation, though.

Parseltongue??
Topic archived. No new replies allowed.