The following palnumber demonstrations follow the algorithms developed in the Palindrome-number problem section and parallel the cpalnumber.cpp programs presented previously in this chapter. However, the following demonstrations replace the C-strings used in the earlier versions with instances of the C++ string class. Presented first is a string version of the "finger" solution. The next example creates a function that converts integers into string objects, a function similar to the itoa function we wrote previously. The last demonstration presents a string version of the "reverse" solution.
Programming The "Finger" Solution
Converting Numbers To Strings
Visual Studio 2012 added the to_string function to C++. Before then, the palnumber example included its own version of to_string. Although writing our own to_string function is no longer necessary, doing so is still a good learning exercise. Internally, computers store textual data in a coded format. Java uses Unicode, a 2-byte integer, to encode text. C++ can represent text as a 1- or 2-byte (wide) character. We focus on 1-byte characters encoded with the older American Standard Code for Information Interchange (ASCII) scheme.
Examine the ASCII table, especially the middle column; look at the codes for the characters '0' through '9' (the red characters). The character '0' is represented by the numeric code 48 (base 10), and the character '9' is represented by the numeric code 57 (base 10). Also, notice that the characters between '0' and '9' are represented by consecutive code values.
Given an integer, our task is to convert that integer into a string that looks like the number. The solution involves working with an integer one digit at a time. If we work from left to right, the string will contain the digits in the correct order. However, working from left to right is difficult because we don't know how many digits the number has. Working backward (right to the left) is easier but converts the digits in reverse order. The string concatenation operator allows us to solve this problem elegantly: we append or concatenate the new characters on the right side of the string as we build it.
Before using our conversion function, we must modify the palnumber.cpp code in Figure 1 in two ways:
Add a prototype at the top of the file: string my_to_string(int n);
Replace the function call to_string(square); with
my_to_string(square);
The Reverse Solution
The definition of a palindrome is a string that reads the same forwards and backward (without considering spaces or other punctuation characters). The program described below solves the palindrome-number problem based on the definition. It reverses the candidate string and then compares it to the original string. If the two strings are the same (i.e., equal), then the candidate string is a palindrome; if the two strings are not the same, then the candidate is not a palindrome.
string reverse(string s)
{
string r;
for (int i = 0; i < s.length(); i++) // (a)
r += s[s.length() - 1 - i]; // (b)
return r;
}
string reverse(string s)
{
string r;
for (char c : s) // (c)
r = c + r; // (d)
return r;
}
The string reverse function. The C++ string class provides many useful functions and operators but not a function to reverse a string, so we must write our own. Both versions of the reverse function share three common features: First, the string that it reverses is the function's argument; second, the function creates a local string, r, where it constructs the reversed string; and finally, both versions return the reversed string as the function's return value.
A "traditional" for-loop accesses each character, from the beginning to the end, of the string.
The expression s.length() - 1 - i indexes into the string beginning with the last character and moves backward (i.e., right to left) as the loop control variable increases. The += string operator concatenates the characters extracted from the original string to the right of any characters already in the reversed string.
A for-range loop accesses the characters in the original string in the forward (i.e., left to right) direction one at a time.
The expression c + r concatenates the character extracted from the original string to the left of the characters already added to the reversed string. The new string created by the concatenation operation replaces the contents of (i.e., is stored in) the reversed string, r.
Comparing the C-string and string class solutions for the palindrome-number problem, including the three different versions of the reverse function, suggests three elaborating questions that we should ask ourselves:
The C-string solution copied the candidate string before reversing, but the string class solution does not. Why are the solutions different?
The for-loop in the C-string version iterates for one-half the length of the string, but both string class versions iterate for the string's full length. Why is there a difference?
The two string class versions use different concatenation operators to build the reversed string. The traditional for-loop uses the concatenation-with-assignment operator, +=, which concatenates the new character to the right of the reversed string. The for-range loop uses separate operators: + and =, and c+r concatenates the new character to the left of the reversed string. Can you figure out why there is a difference?
Downloadable Code
palnumber.cpp (formatted with tab stops set at 8 characters)
reverse1.cpp (formatted with tab stops set at 8 characters)
reverse2.cpp (formatted with tab stops set at 8 characters)