Visit the pangram exercise on Exercism to read the full instructions and download the exercise files.
Dig Deeper
bitset.all()
bitset.all()
pangram.h
#pragma once
#include <string_view>
namespace pangram {
bool is_pangram(std::string_view phrase);
} // namespace pangram
pangram.cpp
#include "pangram.h"
#include <bitset>
#include <cctype>
namespace pangram {
bool is_pangram(std::string_view phrase) {
std::bitset<26> letters;
for (const auto c : phrase)
if (std::isalpha(c))
letters.set (std::tolower(c) - 'a');
return letters.all();
}
} // namespace pangram
This approach starts be defining a bitset to keep track of the used letters.
A range-based for loop iterates over all of the characters in the input phrase string_view.
Each character is tested by the isalpha() function to see if it is considered an alphabetic character according to the currently installed C locale.
If the currently installed locale is not suitable for the English alphabet, then std::locale::classic() can be passed to the isalpha() function defined in <locale>, like so:
#include <bitset>
#include <locale>
// code snipped
if (std::isalpha(c, std::locale::classic()))
If the character is alphabetic, then a bit value is set to represent its being used.
The ASCII value of a is subtracted from the character tolower()ed.
If the currently installed locale is not suitable for lowercasing English characters, then std::locale::classic() can be passed to the tolower() function defined in <locale>, like so:
#include <bitset>
#include <locale>
// code snipped
letters.set (std::tolower(c, std::locale::classic()) - 'a');
For example, if the character is A, then A is lowered to a, and the ASCII value of a is subtracted by the ASCII value a to set the bit at position 0 in the bitset to 1.
if the character is Z, then Z is lowered to z, and the ASCII value of z is subtracted by the ASCII value a to set the bit at position 25 in the bitset to 1.
After all of the characters in the input phrase are iterated, the the all() function is used to return if all of the 26 bits are set.
algorithm.all_of()
algorithm.all_of()
pangram.h
#pragma once
#include <string_view>
namespace pangram {
bool is_pangram(std::string_view phrase);
} // namespace pangram
pangram.cpp
#include <algorithm>
#include <cctype>
#include <string>
namespace {
const std::string abc = "abcdefghijklmnopqrstuvwxyz";
}
namespace pangram {
bool is_pangram(std::string_view phrase){
std::string lphrase(phrase.length(), ' ');
std::transform(phrase.begin(), phrase.end(), lphrase.begin(), std::tolower);
return std::all_of(abc.cbegin(), abc.cend(), [lphrase](char c){ return lphrase.find(c) != std::string::npos; });
}
} // namespace pangram
This approach starts by defining a const string to hold all of the lowercased letters of the English alphabet, within an unnamed namespace.
The static keyword used to be used for this, but it was deprecated for this purpose in former versions (and then was later undeprecated.)
Many coders still prefer using the unnamed namespace.
This is_pangram() function starts by defining a string to hold the lowercased letters.
The transform() and tolower() functions are used to place the lowercased letters from the input phrase string_view into that string.
If the currently installed locale is not suitable for lowercasing English characters, then std::locale::classic() can be passed to the tolower() function defined in <locale>, like so:
#include <algorithm>
#include <string>
#include <locale>
// code snipped
std::transform(phrase.begin(), phrase.end(), lphrase.begin(), [](char c){ return std::tolower(c, std::locale::classic()); });
The all_of() function is used test if all of the letters in the English alphabet string are present in the lowercased letters string.
The lambda takes each character from the English alphabet string as an argument and passes it to the find() member function of the lowercased letters string.
If find() does not return npos, then the character was found, and the lambda will return true, otherwise it will return false.
If all of the calls to find() return true, then all_of() will return true.
If any call to find() returns false, then all_of() will return false.
FInally, the is_pangram() function returns the result of calling all_of().
Source: Exercism cpp/pangram