Your
if statements are incorrect -- a comma-separated expression list will always return the value of the
last expression in the list. What you should have is
23 24
|
if (word[1]=='b' || word[1]=='f' || word[1]=='p' || word[1]=='v')
...
|
The next problem is that you are applying a condition that belongs to
all non-vowel elements to only parts of the expression. What if
word[2]
is a vowel?
The way I solved it (I wrote a SOUNDEX program some time ago) was to apply a transform function to each element of the word except the first using the
std::
transform() algorithm:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
char soundex_code( char c )
{
// This is the function that does your code transform,
// as you did above with the if statements.
if (c == 'b' || c == 'f' || c == 'p' || c == 'v') return '1';
...
return c;
}
...
// Here is where we apply the above function to
// every character in the word except the first.
std::transform(
word.begin() + 1,
word.end(),
word.begin() + 1,
&soundex_code
);
|
Finally, your overall algorithm needs a little help.
1. Check that the given
word does not contain any non-alphabetic characters, as SOUNDEX does not accept them.
2. Convert the characters in your string to the same case. I chose UPPERCASE for potential internationalization considerations and because SOUNDEX is supposed to come out with the first letter in uppercase. Do not assume the input is properly formatted! (The
std::
transform() algorithm is useful for this one also.)
3. Apply your letter to SOUNDEX code transformer as above.
4. Collapse adjacent identical digits. (The
std::
unique() algorithm is useful for this.)
5. Remove all non-digits following the first letter. (The
std::
remove_if() algorithm is useful here.)
6. Since it is possible that your resulting string is now shorter than four digits, you must pad it out with zeros. My code looks something like this:
1 2
|
word += "000";
word.resize( 4 );
|
But, of course, that is not the only way to do it.
That's it. Good luck!