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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
class Solution {
private:
unordered_map<char, char> digitMap = {
{'B', '1'}, {'F', '1'}, {'P', '1'}, {'V', '1'},
{'C', '2'}, {'G', '2'}, {'J', '2'}, {'K', '2'}, {'Q', '2'}, {'S', '2'}, {'X', '2'}, {'Z', '2'},
{'D', '3'}, {'T', '3'},
{'L', '4'},
{'M', '5'}, {'N', '5'},
{'R', '6'}
};
unordered_set<char> vowels = {'A', 'E', 'I', 'O', 'U', 'Y', 'W', 'H'};
string removeConsecutiveConsonants(string s) {
string result;
for (int i = 0; i < s.length(); i++) {
if (i == 0 || s[i] != s[i-1] || vowels.count(s[i])) {
result += s[i];
}
}
return result;
}
string removeVowels(string s) {
string result;
for (char c : s) {
if (vowels.find(c) == vowels.end()) {
result += c;
}
}
return result;
}
string replaceWithDigits(string s) {
string result;
for (char c : s) {
if (digitMap.count(c)) {
result += digitMap[c];
}
}
return result;
}
string removeDuplicateDigits(string s) {
if (s.empty()) return s;
string result;
result += s[0];
for (int i = 1; i < s.length(); i++) {
if (s[i] != s[i-1]) {
result += s[i];
}
}
return result;
}
public:
string soundex(string name) {
if (name.empty()) return "";
// Convert to uppercase
transform(name.begin(), name.end(), name.begin(), ::toupper);
// Step 1: Remove consecutive consonants with same sound
name = removeConsecutiveConsonants(name);
// Step 2: Keep first letter
char firstLetter = name[0];
string remaining = name.substr(1);
// Step 3: Remove vowels
remaining = removeVowels(remaining);
// Step 4: Replace consonants with digits
string digits = replaceWithDigits(remaining);
// Remove consecutive duplicate digits
digits = removeDuplicateDigits(digits);
// Step 5: Pad or truncate to 3 digits
while (digits.length() < 3) {
digits += '0';
}
if (digits.length() > 3) {
digits = digits.substr(0, 3);
}
return string(1, firstLetter) + digits;
}
};
|