The X-Y answer on the vast majority of modern systems is don't bother.
You can take advantage of the fact that practically every character encoding used today stores the alphabet in one sequentially-ordered contiguous block. A is followed by B, B is followed by C, etc... on to Z. This allows you to do simple math tricks on letters to convert the letter to a number. For example the letter C minus the letter A , 'C' - 'A', is 2, the distance between c and a.
Some character sets, EBCDIC was discussed in the comments above, are not sequential or contiguous for reasons that are out of scope for discussion here. They are rare, but occasionally you will find one. When you do... Well, most of the other answers here provide suitable solutions.
We can use this to make a mapping of letter values to letters with a simple array:
// a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p, q,r,s,t,u,v,w,x,y, z
int lettervalues[] = {1,3,3,2,1,4,2,4,1,8,5,1,3,1,1,3,10,1,1,1,1,4,4,8,4,10};
So 'c' - 'a'
is 2 and lettervalues[2]
will result in 3, the letter value of C.
No if statements or conditional logic required what-so-ever. All the debugging you need to do is proof reading lettervalues
to make sure you entered the correct values.
As you study more in C++, you will learn that lettervalues
should be static
(current translation unit-only access) and const
(cannot be changed), possibly constexpr
(cannot be changed and fixed at compile time). If you don't know what I'm talking about, don't worry. You'll cover all three later. If not, google them. All are very useful tools.
Using this array could be as simple as
int ComputeWordScore(std::string in)
{
int score = 0;
for (char ch: in) // for all characters in string
{
score += lettervalues[ch - 'a'];
}
return score;
}
But this has two fatal blind spots:
The first is capital letters. Sorry Ayn Rand, but 'A' is not 'a', and 'A'-'a'
is not zero. This can be solved by using std::tolower or std::toupper to convert all input to a known case.
int ComputeWordScore(std::string in)
{
int score = 0;
for (char ch: in) // for all characters in string
{
score += lettervalues[std::tolower(ch) - 'a'];
}
return score;
}
The other is input of characters that aren't letters. For example, '1'. 'a' - '1'
will result in an array index that is not in the array. This is bad. If you're lucky your program will crash, but anything could happen, including looking as though your program works. Read up on Undefined Behaviour for more.
Fortunately this also has a simple fix: Only compute the score for good input. You can test for valid alphabet characters with std::isalpha.
int ComputeWordScore(std::string in)
{
int score = 0;
for (char ch: in) // for all characters in string
{
if (std::isalpha(ch))
{
score += lettervalues[std::tolower(ch) - 'a'];
}
else
{
// do something that makes sense here.
}
}
return score;
}
My something else would be return -1;
. -1 is an impossible word score, so anyone who calls ComputeWordScore
can test for -1 and reject the user's input. What they do with it is not ComputeWordScore
's problem. Generally the stupider you can make a function, the better, and errors should be handled by the closest piece of code that has all the information needed to make a decision. In this case, whatever read in the string would likely be tasked with deciding what to do with bad strings and ComputeWordScore
can keep on computing word scores.