我有一个代码......
var userArray=userIn.match(/(?:[A-Z][a-z]*|\d+|[()])/g);
...将化学式的用户输入分成其组分。
例如,输入Cu(NO3)2N3
将产生
Cu,(,N,O,3,),2,N,3。
在查找整个重量中每个元素的百分比时,我需要计算每个元素输入的次数。
所以在上面的例子中,
Cu : 1 ,
N : 5 ,
O : 6
有关我应该如何做的任何建议?
答案 0 :(得分:2)
没有简单的方法。你需要嵌套和内存,正则表达式不能很好地处理(好吧,真正的 CS regulular表达式根本无法处理它)。
首先,您获得结果正则表达式。这称为Tokenization。
现在,您必须实际解析。
我建议以下方法我会给你伪代码,因为我认为它会更好地演绎。如果您对此有任何疑问,请告诉我:
方法 chemistryExpression (令牌):#Tokens是你的正则表达式的结果
- 的空地图
创建一个名为地图
虽然下一个标记是字母,但要使用它(将其从标记中删除)
2.1将字母添加到出现1的地图中,如果已经在地图中,则将其增加1
如果下一个标记是
(
,请使用它:#处理嵌套3.1将 parseExpression (标记)中的出现次数添加到地图中(注意,标记已更改)
3.2删除您刚刚遇到的额外
)
num =使用令牌而下一个令牌是数字并转换为int
- 乘以地图中所有代币的出现次数
通过 num
- 醇>
返回地图
地图可以只是一个对象。
添加到地图是检查密钥是否存在,如果不存在,则将其设置为1,如果存在,则将其值增加1。
可以使用for... in
循环进行乘法。
此解决方案是递归这意味着您正在使用一个自我调用的函数(chemistryExpression)。这个解析器是递归下降解析器的一个非常基本的例子,可以很好地处理嵌套。
常识和良好实践需要两种方法
tokens[0]
tokens.unshift()
答案 1 :(得分:0)
对于userArray中的每个值,检查是否存在下一个元素anf,如果下一个元素是数字,如果是,则将此数字添加到当前元素类型的计数中,否则添加1.您可以使用对象作为用于存储每种不同元素类型的计数的映射:
var map = { }
map[userArray[/*an element*/] = ...
编辑:如果你的数字长于一个数字,那么在循环中,而下一个是数字,将所有数字连接成一个字符串和parseInt()