4
bool isUpper(char ch) {5
return ch >= 65 && ch <= 90;8
bool isLower(char ch) {9
return ch >= 97 && ch <= 122;12
bool isLetter(char ch) {13
return isUpper(ch) || isLower(ch);16
bool isNumber(char ch) {17
return ch >= 48 && ch <= 57;20
void addKey(map<string, long int> &count, string key, long int value) {21
if (count.find(key) != count.end()) {22
count[key] = count[key] + value;28
// very specific utility function29
string buildName(string formula, int &i) {31
name.push_back(formula[i]);32
if (isUpper(formula[i])) {35
if (i == formula.length() - 1) {38
while (isLower(formula[i - 1])) {39
name.push_back(formula[i - 1]);42
name.push_back(formula[i - 1]);44
reverse(name.begin(), name.end());48
// very specific utility function49
long int buildCount(string formula, int &i, vector<long int> &stack) {50
long int num = formula[i] - '0';55
while (isNumber(formula[i - 1])) {57
num = (formula[i - 1] - '0') * place + num;63
string countOfAtoms(string formula) {65
map<string, long int> count;66
vector<long int> stack;69
long int num = -1; // -1 indicates a number reset, ie, count = 171
// iterator i is passed by reference to keep track of72
// the substrings that are builded, ie, atom74
int i = formula.length() - 1;76
// here we need the number after the bracket close. This is77
// either 1 or num depending on whether we built a number before78
if (formula[i] == ')') {79
if (i + 1 <= formula.length() - 1 && isNumber(formula[i + 1])) {81
factor = factor * num;87
// here is why we need a stack. Remove latest factor that was added.88
else if (formula[i] == '(') {89
factor = factor / stack.back();92
// once we detect a letter, we know it can only be a word. num gives us93
// the atom subscript and factor gives us the molecular count.94
else if (isLetter(formula[i])) {95
name = buildName(formula, i);97
addKey(count, name, 1 * factor);99
addKey(count, name, num * factor);101
num = -1; // reset number102
} else if (isNumber(formula[i])) {103
num = buildCount(formula, i, stack);108
// arrange name and count in a string109
map<string, long int>::iterator it;110
for (it = count.begin(); it != count.end(); it++) {111
ans = ans + it->first;112
if (it->second != 1) {113
ans = ans + to_string(it->second);