classSolution { public: string countOfAtoms(string formula){ int i = 0, n = formula.length();
auto parseAtom = [&]() -> string { string atom; atom += formula[i++]; // 扫描首字母 while (i < n && islower(formula[i])) { atom += formula[i++]; // 扫描首字母后的小写字母 } return atom; };
auto parseNum = [&]() -> int { if (i == n || !isdigit(formula[i])) { return1; // 不是数字,视作 1 } int num = 0; while (i < n && isdigit(formula[i])) { num = num * 10 + int(formula[i++] - '0'); // 扫描数字 } return num; };
stack<unordered_map<string, int>> stk; stk.push({}); while (i < n) { char ch = formula[i]; if (ch == '(') { i++; stk.push({}); // 将一个空的哈希表压入栈中,准备统计括号内的原子数量 } elseif (ch == ')') { i++; int num = parseNum(); // 括号右侧数字 auto atomNum = stk.top(); stk.pop(); // 弹出括号内的原子数量 for (auto &[atom, v] : atomNum) { stk.top()[atom] += v * num; // 将括号内的原子数量乘上 num,加到上一层的原子数量中 } } else { string atom = parseAtom(); int num = parseNum(); stk.top()[atom] += num; // 统计原子数量 } }
auto &atomNum = stk.top(); vector<pair<string, int>> pairs; for (auto &[atom, v] : atomNum) { pairs.emplace_back(atom, v); } sort(pairs.begin(), pairs.end());
string ans; for (auto &p : pairs) { ans += p.first; if (p.second > 1) { ans += to_string(p.second); } } return ans; } };
public String parseAtom() { StringBuffersb=newStringBuffer(); sb.append(formula.charAt(i++)); // 扫描首字母 while (i < n && Character.isLowerCase(formula.charAt(i))) { sb.append(formula.charAt(i++)); // 扫描首字母后的小写字母 } return sb.toString(); }
publicintparseNum() { if (i == n || !Character.isDigit(formula.charAt(i))) { return1; // 不是数字,视作 1 } intnum=0; while (i < n && Character.isDigit(formula.charAt(i))) { num = num * 10 + formula.charAt(i++) - '0'; // 扫描数字 } return num; } }
StringBuilder sb = new StringBuilder(); foreach (KeyValuePair<string, int> pair in pairs) { string atom = pair.Key; int count = pair.Value; sb.Append(atom); if (count > 1) { sb.Append(count); } } return sb.ToString(); }
publicstringParseAtom() { StringBuilder sb = new StringBuilder(); sb.Append(formula[i++]); // 扫描首字母 while (i < n && char.IsLower(formula[i])) { sb.Append(formula[i++]); // 扫描首字母后的小写字母 } return sb.ToString(); }
publicintParseNum() { if (i == n || !char.IsNumber(formula[i])) { return1; // 不是数字,视作 1 } int num = 0; while (i < n && char.IsNumber(formula[i])) { num = num * 10 + formula[i++] - '0'; // 扫描数字 } return num; } }
funccountOfAtoms(formula string)string { i, n := 0, len(formula)
parseAtom := func()string { start := i i++ // 扫描,跳过首字母 for i < n && unicode.IsLower(rune(formula[i])) { i++ // 扫描首字母后的小写字母 } return formula[start:i] }
parseNum := func() (num int) { if i == n || !unicode.IsDigit(rune(formula[i])) { return1// 不是数字,视作 1 } for ; i < n && unicode.IsDigit(rune(formula[i])); i++ { num = num*10 + int(formula[i]-'0') // 扫描数字 } return }
stk := []map[string]int{{}} for i < n { if ch := formula[i]; ch == '(' { i++ stk = append(stk, map[string]int{}) // 将一个空的哈希表压入栈中,准备统计括号内的原子数量 } elseif ch == ')' { i++ num := parseNum() // 括号右侧数字 atomNum := stk[len(stk)-1] stk = stk[:len(stk)-1] // 弹出括号内的原子数量 for atom, v := range atomNum { stk[len(stk)-1][atom] += v * num // 将括号内的原子数量乘上 num,加到上一层的原子数量中 } } else { atom := parseAtom() num := parseNum() stk[len(stk)-1][atom] += num // 统计原子数量 } }
atomNum := stk[0] type pair struct { atom string num int } pairs := make([]pair, 0, len(atomNum)) for k, v := range atomNum { pairs = append(pairs, pair{k, v}) } sort.Slice(pairs, func(i, j int)bool { return pairs[i].atom < pairs[j].atom })
ans := []byte{} for _, p := range pairs { ans = append(ans, p.atom...) if p.num > 1 { ans = append(ans, strconv.Itoa(p.num)...) } } returnstring(ans) }
constparseNum = () => { if (i === n || isNaN(Number(formula[i]))) { return1; // 不是数字,视作 1 } let num = 0; while (i < n && !isNaN(Number(formula[i]))) { num = num * 10 + formula[i++].charCodeAt() - '0'.charCodeAt(); // 扫描数字 } return num; }