如何拆分含连续大小写字母的字符串获取分子原子数?代码求助
搞定原子计数的合并问题:思路+修正代码
嘿,你遇到的问题其实很典型——没把完整的元素符号(比如Cl、Na)当成一个整体来处理,而是单个字符拆开来搞,大写字母单独加1,小写字母直接贴上去,难怪会出C1l、N1a这种奇怪的结果。咱们来一步步修正:
先理清楚原子符号的规则
原子符号可不是随便拆的:
- 必须以大写字母开头
- 后面可以跟0个或多个小写字母(比如O是单字母,Cl、Na是双字母,甚至有些更长的稀有元素符号,但常见的都是1-2个字符)
- 元素后面可能跟着数字(代表数量,没写数字的话默认是1)
你之前的循环是逐个字符判断,完全忽略了“大写+后续小写是一个整体”这个关键点,所以才会把Cl拆成C和l分别处理。
修正后的完整代码
function countAtoms(molecule) { // 用对象存储每个元素的总数量 const elementCounts = {}; let i = 0; const totalLength = molecule.length; while (i < totalLength) { // 第一步:提取完整的元素符号 let currentElement = molecule[i]; i++; // 检查下一个字符是否为小写字母,是的话拼接到元素名中 while (i < totalLength && molecule[i] === molecule[i].toLowerCase()) { currentElement += molecule[i]; i++; } // 第二步:提取元素后面的数量(如果存在) let countStr = ''; while (i < totalLength && !isNaN(molecule[i])) { countStr += molecule[i]; i++; } // 无数字时默认数量为1 const count = countStr ? parseInt(countStr, 10) : 1; // 第三步:统计数量,重复元素则累加 if (elementCounts[currentElement]) { elementCounts[currentElement] += count; } else { elementCounts[currentElement] = count; } } // 第四步:转换成你需要的格式,比如Cl1Na1 let result = ''; for (const [elem, cnt] of Object.entries(elementCounts)) { result += `${elem}${cnt}`; } console.log(result); return result; } // 测试用例验证效果 countAtoms("NaCl"); // 输出 "Na1Cl1" countAtoms("Fe2O3"); // 输出 "Fe2O3" countAtoms("H2O"); // 输出 "H2O1" countAtoms("NaClNaCl"); // 输出 "Na2Cl2"
为啥这么改?
- 提取完整元素:遇到大写字母后,不会立刻处理,而是先把后面跟着的所有小写字母都纳入进来,确保拿到的是Cl、Na这种完整的元素名,而非拆分的单个字符。
- 处理数量:元素后面如果有数字,会提取连续的数字串(比如Fe2O3里的2和3),没有数字就默认给1,符合化学符号的默认规则。
- 统计累加:用对象存储计数,遇到重复元素会自动累加数量,避免重复输出相同元素的信息。
- 生成结果:最后遍历统计对象,把每个元素和对应数量拼接成你需要的格式,完美解决拆分问题。
这样处理后,就能正确识别完整的元素符号,不会再出现奇怪的拆分输出啦~
内容的提问来源于stack exchange,提问作者xnok
相关产品推荐
相关产品推荐

