我有一个代码...
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
关于我应该如何做这件事有什么建议吗?
最佳答案
你需要构建一个解析器
没有简单的解决方法。您需要嵌套和内存,正则表达式无法很好地处理(好吧,真正的 CS 正则表达式根本无法处理)。
首先,您会得到您拥有的结果正则表达式。这叫做 Tokenization .
现在,您必须实际解析它。
我建议下面的方法我会给你伪代码因为我认为它会更好地演绎。如果您对此有任何疑问,请告诉我:
method chemistryExpression(tokens): #Tokens is the result of your regex
Create an empty map called map
While the next token is a letter, consume it (remove it from the tokens)
2.1 Add the letter to the map with occurrence 1 or increment it by one if it's already inside the map
If the next token is
(
, consume it: # Deal with nesting3.1 Add the occurrences from parseExpression(tokens) to the map (note, tokens changed)
3.2 Remove the extra
)
you've just encounterednum = consume tokens while the next token is a number and convert to int
Multiply the occurances of all tokens in the map by num
Return the map
实现建议
map 可以只是一个对象。
添加到map是检查key是否存在,如果不存在,则将其设置为1,如果存在,则将其值加1。
乘法可以使用
for...in
循环来完成。
此解决方案是递归的,这意味着在这种情况下您使用的是一个调用自身 (chemistryExpression) 的函数。该解析器是递归下降解析器的一个非常基本的示例,可以很好地处理嵌套。
常识和良好实践需要两种方法
- peek - token 中的下一个 token 是什么,这是
tokens[0]
- next - 从 tokens 中获取下一个 token,这是
tokens.unshift()
- peek - token 中的下一个 token 是什么,这是
关于javascript - 计算数组中字符串的出现次数(javascript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17374783/