
题目分析
- 这道题要求我们统计原子的数量,考虑正向遍历需要等到括号内的值计算完毕才能得到当前括号的倍数,所以我们采用反向遍历的方式,currentCount表示当读取到的数量,currentName表示原子名称,topRatio表示当前栈顶倍数,用一个栈来存储每个括号的倍数。遇到‘)’向栈中压入currentCount并且重新计算topRatio,遇到‘(’退栈并计算topRatio。当遇到大写字符时表示原子名称已经读取完成,进行一次写入操作。这里我们用Name作为键Count做为值的对象来存储答案,返回时对对象的keys进行排序之后reduce即可。
- sort排序默认按照字典序排序
代码
function countOfAtoms(formula: string): string {
const result: { [key: string]: number } = {};
const stack = [];
let topRatio = 1;
let currentName = '';
let currentCount = '';
const add = (key: string, count: number) => {
result[key] = count + (result[key] || 0);
};
for (let i = formula.length - 1; i >= 0; --i) {
const char = formula.charAt(i);
const codePoint = char.codePointAt(0) as number;
if (codePoint >= 97) {
currentName = char + currentName;
} else if (codePoint >= 65) {
add(char + currentName, (+currentCount || 1) * topRatio);
currentCount = '';
currentName = '';
} else if (codePoint >= 48) {
currentCount = char + currentCount;
} else if (char === ')') {
stack.push(+currentCount || 1);
topRatio *= +currentCount || 1;
currentCount = '';
} else {
topRatio /= stack.pop() as number;
}
}
return Object.keys(result)
.sort()
.reduce(
(res, key) => (res += key + (result[key] === 1 ? '' : result[key])),
''
);
}