题目
样例好似有毒,不知道是我孤陋寡闻,还是出题人见多识广,竟然还有Be32,,(H),,真牛逼哇。
导致右括号后一个不一定是数字,还可能是元素了,导致我每次还要las=1,因为比如(H)O2,2不该入栈的。但我们的代码是遇见右括号就要入栈,所以要las=1,将1入栈,相当于没入。
class Solution {
typedef pair<string,int> pi;
public:
string cal(int n){342得到"342"
string res="";
while(n) res+=n%10+'0',n/=10;
reverse(res.begin(),res.end());
return res;
}
string countOfAtoms(string s) {
map<string,int>mp;
int n=s.size();
int sum=1,las=1;stack<int>st;
for(int i=n-1;i>=0;--i){
//是数字不一定入栈,数字前面是左括号 才能入栈
if(s[i]>='0'&&s[i]<='9'){//当一个数字前面是括号时 才入栈,才sum*=该数
int tmp=1;las=(s[i]-'0')*tmp;
while(s[i-1]>='0'&&s[i-1]<='9') tmp*=10,las+=(s[i-1]-'0')*tmp,--i;//i-1一定>=0
continue;
}
else if(s[i]==')') sum*=las,st.push(las);//因为是左括号,所以要把las这个数字push到栈
else if(s[i]>='A'&&s[i]<='Z') {
string tmp="";tmp+=s[i];
int tmpsum=sum;
if(i+1<n&&s[i+1]>='0'&&s[i+1]<='9') tmpsum*=las;//元素后面是数字,应该mp[tmp]+=sum*las;
mp[tmp]+=tmpsum;
}
else if(s[i]>='a'&&s[i]<='z') {
string tmp="";tmp+=s[i-1],tmp+=s[i];
int tmpsum=sum;
if(i+1<n&&s[i+1]>='0'&&s[i+1]<='9') tmpsum*=las;//元素后面是数字,应该mp[tmp]+=sum*las;
mp[tmp]+=tmpsum,--i;
}
else if(s[i]=='(') sum/=st.top(),st.pop();
las=1;//比如Mg(OH)O3,比如这时las=3,到了OH)这里的右括号 应该sum*=las了,所以要las=1
}
vector<pi>vec;string ans="";
for(map<string,int>::iterator it=mp.begin();it!=mp.end();++it) vec.push_back(make_pair(it->first,it->second));
sort(vec.begin(),vec.end());//将string按字典序排序
for(auto p:vec){
ans+=p.first;
if(p.second!=1) ans+=cal(p.second);//出现数量为1,就不需要标数量了
}
return ans;
}
};