视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
关于JavaScript解析化学分子式的代码实例分享
2020-11-27 20:23:56 责编:小采
文档

给定一个化学分子式的字符串,统计每一种元素原子的数量。

例如:

水分子'H2O',它的构成是2个氢原子,1个氧原子,用对象表示为{H: 2, O: 1}。

再如氢氧化镁'Mg(OH)2',用对象表示是{Mg: 1, O: 2, H: 2}。

再来个复杂点的'K4[ON(SO3)2]2',表示为{K: 4, O: 14, N: 2, S: 4}。

这些分子式中,有可能出现很多成双成对的括号,包括圆的,方的,卷曲的,括号后面如果跟随了数字,那就表明,括号里的原子数量要乘以多少倍。例如’Fe(NO3)2’,它由一个铁原子,两个氮原子,六个氧原子组成。

这个题目的难点在于括号的处理上,有三种类型的括号,括号与括号之间有嵌套,有N对括号的情况。

//利用进出栈括号相抵,求对应括号的位置
function findBracket(str){
 var stack = ["("];
 for(var i=0;i<str.length;i++){
 var chr = str.charAt(i);
 if(chr === "("){
 stack.push(chr);
 }
 else if(chr === ")"){
 stack.pop();
 }
 if(!stack.length){
 return i;
 }
 }
}

function parseMolecule(formula) {
	//存放结果的hash
 var hash = {};
 //先将所有的括号统一为圆括号
 formula = formula.replace(/{/g ,"(")
 .replace(/}/g ,")")
 .replace(/\[/g ,"(")
 .replace(/\]/g ,")");
 //遍历方法
 var traverse = function(formula){
 var str = "";
	//存放数字之前的字符串
 var prev = "";
 for(var i=0;i<formula.length;i++){
 var chr = formula.charAt(i);
	//如果当前字符是数字
 if(!isNaN(chr)){
	//如果右边的字符也是数字
	//如"O12",十二个氧原子
 if(!isNaN(formula.charAt(i+1))){
	//"1" + "2" = "12"
 chr += formula.charAt(i+1);
 i++;
 }
	//转化为数字
	//"12" => 12
 chr = chr - 0;
	//拼接"O"
	//=> "OOOOOOOOOOOO"
 while(chr--){
 str += prev;
 }
 }
 else if(chr === "("){
	//剪切两个括号之间的内容,递归
	//如"Mg(OH)2"
	//"OH"递归
 var temp = formula.slice(i+1);
 var pos = findBracket(temp);
	//=>"OH"
 prev = traverse(temp.slice(0,pos));
	//右括号位置")"
 i = pos + i + 1;
	//如果右括弧右边不是数字,直接拼接"OH",无须相乘
 if(isNaN(formula.charAt(i+1))){
 str += prev;
 }
 }//如果当前字符右边是数字
 else if(formula.charAt(i+1) && !isNaN(formula.charAt(i+1))){
 prev = chr;
 }//如果当前字符右边是小写字母,再右边是数字
 else if(formula.charCodeAt(i+1) >= 97 && formula.charCodeAt(i+1) <= 122 && formula.charAt(i+2) && !isNaN(formula.charAt(i+2))){
 prev = chr + formula.charAt(i+1);
 i++;
 }
 else{
 str += chr;
 }
 }
	//如"Mg(OH)2"
	//=> "MgOHOH"
 return str;
 };
 
 var result = traverse(formula);
 //将字符串遍历,在hash中存储
 for(var i=0;i<result.length;i++){
 var nextCode = result.charCodeAt(i+1);
	//例如"Mg","Fe","Cu"这样一个大写接一个小写的情况
 if(nextCode >= 97 && nextCode <= 122){
 var key = result.charAt(i) + result.charAt(i+1);
 i++;
 }
 else{
 var key = result.charAt(i);
 }
 if(hash[key]){
 hash[key] = hash[key] + 1;
 }
 else{
 hash[key] = 1;
 }
 }
 
 return hash;
}

下载本文
显示全文
专题