假设我们有一个化学式;我们必须找到每个原子的数量。
原子元素将始终以大写字符开头,可以有零个或多个小写字母表示名称。如果计数大于1,则可以跟随1或多个表示该元素计数的数字。但是,如果计数为1,则不跟随数字。例如,H2O和H2O2均有效,但H1O2无效。
因此,如果输入类似于Na2(CO)3,则输出将为C3Na2O3,因此这表示3个碳(C),2个钠(Na),3个氧(O)。
为了解决这个问题,我们将遵循以下步骤-
定义一个函数makeRet()
,这将占用一张映射m,
ret:=空字符串
对于m中的每个键值对“ it”-
ret:= ret +它的值作为字符串
ret:= ret +键
如果它的值> 1,则-
返回ret
定义一个函数countOfAtoms()
,需要s,
定义一张映射
定义一个堆栈st
i:= 0,n:= s的大小
当我<n时,-
名称:=空字符串
值:= 0
名称:=名称+ c
而(i <n和s [i]在范围“ a”至“ z”中)执行-
而(i <n和s [i]在0到9的范围内),则执行-
val:=(如果val与0相同,则为1,否则为val)
m [name]:= m [name] + val
名称:=名称+ s [i]
(将i增加1)
val:= val * 10 +(s [i]-ASCII'0')
(将i增加1)
值:= 0
而(i <n和s [i]在0到9的范围内),则执行-
定义一个map temp:= st的top元素
从st删除元素
对于m中的每个键值对“ it”-
m:=温度
val:= val * 10 +(s [i]-ASCII'0')
(将i增加1)
它的值:=它的值* val
temp [它的键]:= temp [它的键] +它的值
将m插入st
m:=定义一张映射
c:= s [i]
(将i增加1)
如果c与'('相同,则-
否则,当c与')'相同时,则-
除此以外
返回makeRet(m)
让我们看下面的实现以更好地理解-
#include <bits/stdc++.h> using namespace std; class Solution { public: string makeRet(map<string, int> m){ string ret = ""; for (auto& it : m) { ret += it.first; if (it.second > 1) { ret += to_string(it.second); } } return ret; } string countOfAtoms(string s){ map<string, int> m; stack<map<string, int> > st; int i = 0; int n = s.size(); while (i < n) { char c = s[i]; i++; if (c == '(') { st.push(m); m = map<string, int>(); } else if (c == ')') { int val = 0; while (i < n && s[i] >= '0' && s[i] <= '9') { val = val * 10 + (s[i] - '0'); i++; } map<string, int> temp = st.top(); st.pop(); for (auto& it : m) { it.second *= val; temp[it.first] += it.second; } m = temp; } else { string name = ""; int val = 0; name += c; while (i < n && s[i] >= 'a' && s[i] <= 'z') { name += s[i]; i++; } while (i < n && s[i] >= '0' && s[i] <= '9') { val = val * 10 + (s[i] - '0'); i++; } val = val == 0 ? 1 : val; m[name] += val; } } return makeRet(m); } }; main(){ Solution ob; cout << (ob.countOfAtoms("Na2(CO)3")); }
Na2(CO)3
输出结果
C3Na2O3